/**********************************************************************************************************************
 *  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
 *  -------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -----------------------------------------------------------------------------------------------------------------*/
/** \file  File:  ARMBrsHw_CortexR.c
 *      Project:  Vector Basic Runtime System
 *       Module:  BrsHw for all platforms with ARM core Cortex-R
 *     Template:  This file is reviewed according to Brs_Template@Implementation[1.03.12]
 *
 *  \brief Description:  This is a global, platform-independent file for the ARM-BRS.
 *                       This file includes all non-platform dependent functions.
 *                       All the (platform depending) rest needs to be defined in BrsHw.c
 *
 *  \attention Please note:
 *    The demo and example programs only show special aspects of the software. With regard to the fact
 *    that these programs are meant for demonstration purposes only, Vector Informatik liability shall be
 *    expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  REVISION HISTORY
 *  -------------------------------------------------------------------------------------------------------------------
 *  Refer to ARMBrsHw_CortexR.h.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  EXAMPLE CODE ONLY
 *  -------------------------------------------------------------------------------------------------------------------
 *  This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration.
 *  The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither
 *  intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or
 *  implementations must be tested with diligent care and must comply with all quality requirements which are necessary
 *  according to the state of the art before their use.
 *********************************************************************************************************************/

#define ARMBRSHW_CORTEXR_SOURCE

/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/
#include "BrsHw.h"

#if !defined (BRS_DISABLE_OS_USAGE)
  /* BootManager, FlashBootLoader, HSM-Updater and HypervisorMaster execution instances do not use an OS. Define is set in BrsMain.h */
  #include "Os.h"
#endif

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#if (ARMBRSHW_CORTEXR_VERSION != 0x0205u)
  #error "Header and source file are inconsistent!"
#endif
#if (ARMBRSHW_CORTEXR_BUGFIX_VERSION != 0x05u)
  #error "Different versions of bugfix in Header and Source used!"
#endif

/**********************************************************************************************************************
 *  CONFIGURATION CHECK
 *********************************************************************************************************************/
#if defined (BRS_COMP_LLVMTEXASINSTRUMENTS)

#else
  #error "Unknown compiler specified!"
#endif

#if !defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) && !defined (BRS_FIRST_EXECUTION_INSTANCE)
# if !defined (BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE)
  /* As intvect_CoreExceptions is not available within non-First-Execution-Instance binaries, it is necessary to
     hardly configure the address of intvect_CoreExceptions for your platform additionally.
     This is needed for the exception vector change within BrsHw_ExceptionTable_Init(). */
  #error "BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE needs to be defined in BrsHw.h of your platform!"
# endif
#endif

#if (BRSMAIN_VERSION < 0x0221u)
  /* At least BrsMain 2.21.00 is needed for Hypervisor support and definition of BRS_DISABLE_OS_USAGE */
  #error "BrsMain of at least version 2.21.00 is needed for this BrsHw package!"
#endif

/**********************************************************************************************************************
 *  DEFINITION + MACROS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL CONST VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL VARIABLES AND LOCAL HW REGISTERS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  CONTROLLER CONFIGURATION REGISTERS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  LOCAL CONST VARIABLES
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  PROTOTYPES OF GLOBAL FUNCTIONS
 *********************************************************************************************************************/
#if defined (BRS_FIRST_EXECUTION_INSTANCE)
extern void intvect_CoreExceptions(void);
#endif

#if defined (BRS_ENABLE_OS_MULTICORESUPPORT)
extern ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType BrsHw_intvect_CoreExceptions_list[BRS_CPU_CORE_AMOUNT-1];
#endif

/**********************************************************************************************************************
 *  PROTOTYPES OF LOCAL FUNCTIONS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  FUNCTION DEFINITIONS
 *********************************************************************************************************************/

/*****************************************************************************/
/* @brief      Disable the global system interrupt.
 * @pre        Must be the first function call in main@BrsMain
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from main@BrsMain at power on initialization
 *****************************************************************************/
void BrsHwDisableInterruptAtPowerOn(void)
{
  /* Disable IRQ, FIQ */
  __asm(" MRS R0, CPSR ");       /* Read CPSR Register */
  __asm(" ORR R0, R0, #0x040 "); /* Set Asynchronous FIQ Mask bit */
  __asm(" ORR R0, R0, #0x080 "); /* Set Asynchronous IRQ Mask bit */
  __asm(" MSR CPSR_c, R0 ");     /* Write CPSR Register (only bits [7:0]) */

#if defined (BRSHW_DISABLE_INTERRUPT_AT_POWERON_HOOK_AVAILABLE)
  /* used to configure additional, platform specific registers (e.g. VIC)
     BRSHW_DISABLE_INTERRUPT_AT_POWERON_HOOK_AVAILABLE to be defined in BrsHw.h */
  BrsHwDisableInterruptAtPowerOn_Hook();
#endif
}

/*****************************************************************************/
/* @brief      Copy exception vectors to active exception table
 * @pre        -
 * @param[in]  ExcVecLabel - address of the core exception table
 *             IntVecLabel - address of the interrupt vector table
 *             Use BRS_DEFINE_ADDRESS_UNUSED for unused values
 * @param[out] -
 * @return     -
 * @context    Function is called from main@BrsMain at power on initialization
 *****************************************************************************/
void BrsHw_ExceptionTable_Init(Brs_AddressOfConstType ExcVecLabel, Brs_AddressOfConstType IntVecLabel)
{
  /* VBAR is Undefined/not available on ARMv7-R implementations ->
     Exception vector change is done via overwriting the exception vectors,
     which are placed at an offset of 0x20 bytes just behind the exception table start.
     See ARMv7_Cortex-R_BRS_Exception_Handling.pdf for details of the mechanism!
  */
  int i;
  uint32 addressOfActiveExceptionTable;

#if !defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0)
  uint32 runningCoreId;
#endif

#if defined (BRS_ENABLE_OS_MULTICORESUPPORT)
  uint32 coreFound;
#endif

#if defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0)
  addressOfActiveExceptionTable = 0x0;

#else
  runningCoreId = BrsHw_GetCore();
  if (runningCoreId == BRSHW_INIT_CORE_ID)
  {
# if defined (BRS_FIRST_EXECUTION_INSTANCE)
    addressOfActiveExceptionTable = ((uint32)&intvect_CoreExceptions);
# else
    addressOfActiveExceptionTable = BRSHW_COREEXCEPTIONS_ADDRESS_OF_INIT_CORE;
# endif
  }
  else
  {
# if defined (BRS_ENABLE_OS_MULTICORESUPPORT)
    coreFound = 0;
    for (i=0; i < (BRS_CPU_CORE_AMOUNT-1); i++)
    {
      if (BrsHw_intvect_CoreExceptions_list[i].PhysicalCoreId == runningCoreId)
      {
        addressOfActiveExceptionTable = (uint32)(BrsHw_intvect_CoreExceptions_list[i].CoreExceptions);
        coreFound = 1;
        break;
      }
    }
    if (coreFound == 0)
    {
      BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSHW, (uint16)(__LINE__));
    }
# else
    BrsMainExceptionHandler(kBrsIllegalParameter, BRSERROR_MODULE_BRSHW, (uint16)(__LINE__));
# endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/
  }
#endif /*else BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0*/

  if(ExcVecLabel!=BRS_DEFINE_ADDRESS_UNUSED)
  {
    for (i=0; i<8; i++)
    {
      *((uint32*)(addressOfActiveExceptionTable+0x20+i*4)) = *(uint32*)(((uint32)ExcVecLabel)+0x20+i*4);
    }
  }

#if defined (BRSHW_ECXEPTIONTABLE_INIT_POSTHOOK_AVAILABLE)
  BrsHw_ExceptionTable_Init_PostHook(ExcVecLabel, IntVecLabel);
#endif
}

/*****************************************************************************/
/* @brief      This API is used for the BRS time measurement support to get a
 *             default time value for all measurements with this platform to
 *             be able to compare time measurements on different dates based
 *             on this time result.
 * @pre        Should be called with interrupts global disabled
 * @param[in]  -
 * @param[out] -
 * @return     -
 * @context    Function is called from e.g. component testsuits for calibration
 *****************************************************************************/
void BrsHwTime100NOP(void)
{
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
  BRSHWNOP10();
}

#if !defined (BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE)
/*****************************************************************************/
/* @brief      This API is used to read the core ID of the actual running core
 * @pre        -
 * @param[in]  -
 * @param[out] -
 * @return     Core ID of the actual running core
 * @context    Function is e.g. called from main@BrsMain, to only call HW-init
 *             code once, on the boot core.
 *             In MultiCore setups, additional BRSHW_INIT_CORE_ID must be
 *             declared inside BrsHw.h, to configure the proper core ID value
 *             of that boot core.
 *****************************************************************************/
uint32 BrsHw_GetCore(void)
{
#if (BRS_CPU_CORE_AMOUNT>1)
  uint32 id = 0;
  /* Read out the physical processor number (Multiprocessor affinity register (MPIDR))
   * 0 for Core0, Cluster0
   * 1 for Core1, Cluster0
   * 2 for Core0, Cluster1
   * 3 for Core1, Cluster1
   * 4 for Core0, Cluster2
   * 5 for Core1, Cluster2
   */
  brsHwGetMpidr(id);

  return (((id & 0x0000FF00ul) >> 7) | (id & 3ul));

#else
  /* Stub for SingleCore environments, always returns 0 */
  return 0u;
#endif /*BRS_CPU_CORE_AMOUNT*/
}
#endif /*!BRSHW_PLATFORM_SPECIFIC_GETCORE_AVAILABLE*/
