/*
 * Copyright 2020-2023 Yuntu Microelectronics co.,ltd
 * All rights reserved.
 *
 * YUNTU Confidential. This software is owned or controlled by YUNTU and may only be
 * used strictly in accordance with the applicable license terms. By expressly
 * accepting such terms or by downloading, installing, activating and/or otherwise
 * using the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms. If you do not agree to be
 * bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software. The production use license in
 * Section 2.3 is expressly granted for this software.
 */

/**
 * @page misra_violations MISRA-C:2012 violations list
 *  NONE
 */

/* PRQA S 3387 EOF */

#include "Compiler.h"
#include "Std_Types.h"
#include "system_YTM32B1MD1.h"
#include "YTM32B1MD1_features.h"

#if defined(UNIT_TEST)
#include "inc/fakeWDG.h"
#include "inc/fakeEFM.h"
#else
#include "YTM32B1Mx_CM33_DSP_FP.h"
#include "pSIP_Wdg.h"
#include "pSIP_Efm.h"
#endif

/*==================================================================================================
 *                                  PRIVATE MACRO DEFINITIONS
==================================================================================================*/
#define SRAM_START_ADDR     (0x1FFF8000U)
#define SRAM_END_ADDR       (0x20007FFFU)

/* ----------------------------------------------------------------------------
   -- Core clock
   ---------------------------------------------------------------------------- */

#define PLATFORM_START_SEC_CONFIG_DATA_UNSPECIFIED
#include "Platform_MemMap.h"

/**
 * @brief System clock frequency (core clock)
 *
 * The system clock frequency supplied to the SysTick timer and the processor
 * core clock. This variable can be used by the user application to setup the
 * SysTick timer or configure other parameters. It may also be used by debugger to
 * query the frequency of the debug timer or configure the trace clock speed
 * SystemCoreClock is initialized with a correct predefined value.
 */
uint32 SystemCoreClock = DEFAULT_SYSTEM_CLOCK;

PLATFORM_CONST const ARM_MPU_Region_t MpuRegionCfgTable[1U] =
{
    /*The mpu last region adn attr must be reserved fro flash protect.*/
    /*                    BASE ADDR     SH           RO  NP  XN                            ENDADDR                    ATTR  */
#if FEATURE_EFM_HAS_DATA_FLASH
    {.RBAR = ARM_MPU_RBAR(0x00000000U, ARM_MPU_SH_NON, 1U, 1U, 0), .RLAR = ARM_MPU_RLAR(FEATURE_EFM_DATA_ARRAY_END_ADDRESS, 0U)},
#else
    {.RBAR = ARM_MPU_RBAR(0x00000000U, ARM_MPU_SH_NON, 1U, 1U, 0U), .RLAR = ARM_MPU_RLAR(FEATURE_EFM_MAIN_ARRAY_END_ADDRESS, 0U)},
#endif
};

#define PLATFORM_STOP_SEC_CONFIG_DATA_UNSPECIFIED
#include "Platform_MemMap.h"

#define PLATFORM_START_SEC_CODE
#include "Platform_MemMap.h"

#if (ENABLE_MPU)
/*FUNCTION**********************************************************************
 *
 * Function Name : MpuInit
 * Description   :
 *
 * Implements    : MpuInit_Activity
 *END**************************************************************************/
PLATFORM_FUNC void MpuInit(void)
{
#ifdef SAFLIB_CORTST_EN

#if (1 == M33_CST_SPFPU_TESTS)
#define CST_RAM_TARGET_LEN  (0x80U)
#else
#define CST_RAM_TARGET_LEN  (0x40U)
#endif

    extern uint32 CST_RAM_TARGET0[];
    extern uint32 CST_RAM_TARGET1[];
#endif

    uint32 Rbar = 0;
    uint32 Rlar = 0;
    uint32 Rnr  = 0;

    /*Disable MPU*/
    ARM_MPU_Disable();
    /*Init Attr for region*/

    /*ATTR 0:Normal memory,No caches*/
    ARM_MPU_SetMemAttr(0U, ARM_MPU_ATTR(ARM_MPU_ATTR_MEMORY_(0U, 1U, 0U, 0U), ARM_MPU_ATTR_MEMORY_(0U, 1U, 0U, 0U)));

    /*ATTR 1:Normal memory,No caches*/
    ARM_MPU_SetMemAttr(1U, ARM_MPU_ATTR(ARM_MPU_ATTR_MEMORY_(0U, 1U, 0U, 0U), ARM_MPU_ATTR_MEMORY_(0U, 1U, 0U, 0U)));

    /*Load region configuration of Flash protection for MPU*/
    ARM_MPU_Load(Rnr, &MpuRegionCfgTable[0], 1U);
    ++Rnr;

#ifdef SAFLIB_CORTST_EN
    /* SRAM_START_ADDR - (&CST_RAM_TARGET0-1):
     * SRAM, Normal memory, Non-shareable, non-cacheable. */
    /* Region1:
     * base address SRAM_START_ADDR;
     * Non-shareable,
     * Read/write by any privilege level,
     * Execution only permitted if read permitted;
     * limit address (&CST_RAM_TARGET0-1),
     * Attr0,
     * Region enabled. */
    Rbar = SRAM_START_ADDR;
    Rlar = (uint32)&CST_RAM_TARGET0 - 1U;
    Rbar &= (uint32)~0x1FU;
    Rlar &= (uint32)~0x1FU;
    Rbar |= 0x2U;
    Rlar |= 0x1U;
    ARM_MPU_SetRegion(Rnr, Rbar, Rlar);
    ++Rnr;

    /* &CST_RAM_TARGET0 - (&CST_RAM_TARGET0+CST_RAM_TARGET_LEN-1):
     * SRAM/m33_cst_ram_data_target0, Normal memory, Non-shareable,
     * non-cacheable. */
    /* Region2:
     * base address &CST_RAM_TARGET0;
     * Non-shareable,
     * Read/write by any privilege level,
     * Execution only permitted if read permitted;
     * limit address (&CST_RAM_TARGET0+CST_RAM_TARGET_LEN-1),
     * Attr0,
     * Region enabled. */
    Rbar = (uint32)&CST_RAM_TARGET0;
    Rlar = Rbar + (CST_RAM_TARGET_LEN - 1U);
    Rbar &= (uint32)~0x1FU;
    Rlar &= (uint32)~0x1FU;
    Rbar |= 0x2U;
    Rlar |= 0x1U;
    ARM_MPU_SetRegion(Rnr, Rbar, Rlar);
    ++Rnr;

    /* &CST_RAM_TARGET1 - (&CST_RAM_TARGET1+CST_RAM_TARGET_LEN-1):
     * SRAM/m33_cst_ram_data_target1, Normal memory, Non-shareable,
     * non-cacheable. */
    /* Region3:
     * base address &CST_RAM_TARGET1;
     * Non-shareable,
     * Read/write by privileged code only,
     * Execution only permitted if read permitted;
     * limit address (&CST_RAM_TARGET1+CST_RAM_TARGET_LEN-1),
     * Attr0,
     * Region enabled. */
    Rbar = (uint32)&CST_RAM_TARGET1;
    Rlar = Rbar + (CST_RAM_TARGET_LEN - 1U);
    Rbar &= (uint32)~0x1FU;
    Rlar &= (uint32)~0x1FU;
    Rlar |= 0x1U;
    ARM_MPU_SetRegion(Rnr, Rbar, Rlar);
    ++Rnr;

    /* (&CST_RAM_TARGET1+CST_RAM_TARGET_LEN) - SRAM_END_ADDR:
     * SRAM, Normal memory, Non-shareable, non-cacheable. */
    /* Region4:
     * base address (&CST_RAM_TARGET1+CST_RAM_TARGET_LEN);
     * Non-shareable,
     * Read/write by any privilege level,
     * Execution only permitted if read permitted;
     * limit address SRAM_END_ADDR,
     * Attr0,
     * Region enabled. */
    Rbar = (uint32)&CST_RAM_TARGET1 + CST_RAM_TARGET_LEN;
    Rlar = SRAM_END_ADDR;
    Rbar &= (uint32)~0x1FU;
    Rlar &= (uint32)~0x1FU;
    Rbar |= 0x2U;
    Rlar |= 0x1U;
    ARM_MPU_SetRegion(Rnr, Rbar, Rlar);
    ++Rnr;
#else
    /* SRAM_START_ADDR - SRAM_END_ADDR:
     * SRAM, Normal memory, Non-shareable, non-cacheable. */
    /* Region1:
     * base address SRAM_START_ADDR;
     * Non-shareable,
     * Read/write by any privilege level,
     * Execution only permitted if read permitted;
     * limit address SRAM_END_ADDR,
     * Attr0,
     * Region enabled. */
    Rbar = SRAM_START_ADDR;
    Rlar = SRAM_END_ADDR;
    Rbar &= (uint32)~0x1FU;
    Rlar &= (uint32)~0x1FU;
    Rbar |= 0x2U;
    Rlar |= 0x1U;
    ARM_MPU_SetRegion(Rnr, Rbar, Rlar);
    ++Rnr;
#endif

    /*Enable MPU with background regions enabled. */
    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
}
#endif /* (DISABLE_MPU) */

/*FUNCTION**********************************************************************
 *
 * Function Name : SystemInit
 * Description   : This function disables the watchdog, enables FPU
 * and the power mode protection if the corresponding feature macro
 * is enabled. SystemInit is called from startup_device file.
 *
 * Implements    : SystemInit_Activity
 *END**************************************************************************/
PLATFORM_FUNC void SystemInit(void)
{
    /**************************************************************************/
    /* FPU ENABLE*/
    /**************************************************************************/
#ifdef ENABLE_FPU
    /* Enable CP10 and CP11 coprocessors */
    SCB->CPACR |= ((3UL << 20U) | (3UL << 22U));
#endif /* ENABLE_FPU */
    /**************************************************************************/
    /* EFM CONTRROL */
    /**************************************************************************/
    EFM->CTRL |= EFM_CTRL_DPD_EN_MASK | EFM_CTRL_PREFETCH_EN_MASK;
    /**************************************************************************/
    /* WDOG DISABLE*/
    /**************************************************************************/
#if (DISABLE_WDOG)
    WDG->SVCR = 0xB631;
    WDG->SVCR = 0xC278;
    WDG->CR &= ~WDG_CR_EN_MASK;
#endif /* (DISABLE_WDOG) */

    /**************************************************************************/
    /* MPU ENABLE*/
    /**************************************************************************/
#if (ENABLE_MPU)
    MpuInit();
#endif /* (ENABLE_MPU) */
}

/*FUNCTION**********************************************************************
 *
 * Function Name : SystemCoreClockUpdate
 * Description   : This function must be called whenever the core clock is changed
 * during program execution. It evaluates the clock register settings and calculates
 * the current core clock.
 *
 * Implements    : SystemCoreClockUpdate_Activity
 *END**************************************************************************/
PLATFORM_FUNC void SystemCoreClockUpdate(void)
{
    SystemCoreClock = 120000000U;
}

#define PLATFORM_STOP_SEC_CODE
#include "Platform_MemMap.h"

/*******************************************************************************
 * EOF
 ******************************************************************************/
