/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright 2018-2025 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/



/*******************************************************************************
 * DESCRIPTION   : Loader main function
 ******************************************************************************/
/******************************************************************************
 * @file          loader_main.c
 * - Version      : 0.17
 * @brief         1. IP initialization.
 *                2. Transfer image.
 *                3. Release of used resources.
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 30.11.2021 0.01     First Release
 *         : 14.02.2022 0.02     Changed log output
 *                               Added device version log output
 *                               Removed Include in micro_wait.h
 *                               Removed the parameter setting process to BL31
 *                               Removed LCS judgement
 *                               Memory map change
 *         : 17.02.2022 0.03     Support AArch32
 *         : 22.03.2022 0.04     Support for GSCE[5.4a, 5.4b],[10.3b]
 *                               Support for coverity
 *                               cid:3430806, 3307617, 3430797
 *                               Changed comment
 *         : 10.05.2022 0.05     Integrated processing
 *                               Changed to processing for each device
 *                               Change log output
 *                               Add argument of load_init()
 *         : 16.06.2022 0.06     Change log output
 *                               Support secure boot for S4
 *         : 31.10.2022 0.07     License notation change.
 *         : 07.11.2022 0.08     Added the parameter setting process to BL31
 *                               Added DDR initialization/QOS initialization
 *         : 07.12.2022 0.09     Warning support when log output is disabled
 *         : 15.12.2022 0.10     Support RegionID check
 *         : 04.04.2023 0.11     Removed stdio.h.
 *         : 21.08.2023 0.12     Add support for V4M.
 *         : 23.01.2024 0.13     Add calling of ram_protection_check function.
 *                               Move calling of final_hash_cmp function.
 *         : 10.09.2024 0.14     Updated Region ID and RAM protection setting
 *                               for QNX.
 *         : 11.10.2024 0.15     Updated Region ID and RAM protection setting
 *                               for QNX for V4M.
 *         : 19.12.2024 0.16     Add loading RTOS#1 and RTOS#2 process.
 *                               Add calling ecm_error_enable() function.
 *         : 26.05.2025 0.17     Add argument of OP-TEE boot address to
 *                               smoni_set_param function.
*****************************************************************************/

#include <stdint.h>
#include <loader_main.h>
#include <rst_register.h>
#include <image_load.h>
#include <ip_control.h>
#include <rcar_def.h>
#include <mem_io.h>
#include <log.h>
#include <string.h>
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#include "cpu_on.h"
#include "qos.h"
#include "rtvram.h"
#include "loader_main_common.h"
#include "../ip/ddr/boot_init_dram.h"
#include "access_protection.h"
#if (ECC_ENABLE == 1)
#if (RCAR_LSI == RCAR_V4H)
#include "../ip/ddr/v4h/lpddr5/ecc_enable_v4h.h"
#elif (RCAR_LSI == RCAR_V4M)
#include "../ip/ddr/v4m/lpddr5/ecc_enable_v4m.h"
#endif /* RCAR_LSI == RCAR_V4H */
#endif /* ECC_ENABLE == 1 */
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */
#if (BOOT_MODE == SECURE)
#include "secure_boot.h"
#endif /* BOOT_MODE == SECURE */
/* Time analysis */
#if (1 == (MEASURE_TIME))
	#include <scmt.h>
	#include <scmt_checkpoint.h>
#else
  #define scmt_wait_ticks(x)
  #define store_time_checkpoint(x,y)
  #define print_time_checkpoints(x)
#endif
#if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
#include "axmm_register.h"
#include "ram_protection.h"
#endif
#if (ECM_ERROR_ENABLE == 1)
#if (RCAR_LSI == RCAR_V4H)
#include "../ip/ddr/v4h/lpddr5/ecm_enable_v4h.h"
#elif (RCAR_LSI == RCAR_V4M)
#include "../ip/ddr/v4m/lpddr5/ecm_enable_v4m.h"
#endif /* RCAR_LSI == RCAR_V4H */
#endif /* ECM_ERROR_ENABLE == 1 */
#include <android_ab.h>
#include <emmc_def.h>
#include <emmc_boot.h>

#if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
#define AXMM_DPTSECCR_NUM   (SDRAM_PROTECT_AREA)    /* set 0 to 15 */
#if (OPTEE_LOAD_ENABLE == OPTEE_ENABLE)
#define AXMM_DPTSECCR_NUM2  (SDRAM_PROTECT_AREA2)   /* set 0 to 15 */
#endif /* OPTEE_LOAD_ENABLE == OPTEE_ENABLE */

#define AXMM_DPTSECCR_SECGRP_MASK   (0x00000F00U)
#define AXMM_DPTSECCR_SECGRP_SEC    (0x00000400U)
#define AXMM_DPTSECCR_SECGWP_MASK   (0x0000000FU)
#define AXMM_DPTSECCR_SECGWP_SEC    (0x00000004U)

#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#if (OPTEE_LOAD_ENABLE == OPTEE_DISABLE)
#define DPTRGNCR_PROTECT_AREA       (3U)
#define DPTRGNCR_LINUX_AREA         (6U)
#else
#define DPTRGNCR_PROTECT_AREA       (4U)
#define DPTRGNCR_LINUX_AREA         (9U)
#endif /* OPTEE_LOAD_ENABLE == OPTEE_DISABLE */
#define SECCTRWD_AREA0              (0U)
#define SECCTRWD_AREA2              (2U)

#define AXMM_DPTRGNCR_RGN0RP_MASK   (0x00010000U)
#define AXMM_DPTRGNCR_RGN0RP        (0x00010000U)
#define AXMM_DPTRGNCR_RGN0WP_MASK   (0x00000001U)
#define AXMM_DPTRGNCR_RGN0WP        (0x00000001U)
#define SECCTRWD_SAFG15WP_MASK      (0x00000005U)
#define SECCTRWD_SAFG15WP           (0x00000005U)

static void remove_rgid0_previlege(void);
#endif /* ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M)) */

static void sdram_protection(uint32_t num);
#endif /* ACC_PROT_ENABLE == PROTECTION_ENABLE */

uint32_t loader_main(void)
{
    uint32_t ca_load_num; /* number of load for CA program */
    uint32_t loop;
    uint32_t reg;       /* store register value */
#ifdef MOBIS_PRK3
    int slot = 0;
#endif
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
    int32_t  result;     /* store result of ddr_init() */
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */

    __attribute__((unused))const char *str;
#if (RCAR_LSI == RCAR_S4)
    const char *product_s4      = "S4";
#elif (RCAR_LSI == RCAR_V4H)
    const char *product_v4h     = "V4H";
#elif (RCAR_LSI == RCAR_V4M)
    const char *product_v4m     = "V4M";
#endif /* RCAR_LSI == RCAR_S4 */
    const char *unknown         = "unknown";
#if (BOOT_MODE == SECURE)
    uint32_t bootmode;       /* store boot mode */
#endif /* BOOT_MODE == SECURE */

    LOAD_INFO li[MAX_PLACED];

#if (1 == (MEASURE_TIME))
    scmt_module_start();
    store_time_checkpoint("loader_main", 0);
#endif
/*****************************************************************************
 *  Initialize Hardware
 *****************************************************************************/
    /* IP initialize */
    ip_init();

/*****************************************************************************
 *  Output boot message
 *****************************************************************************/
#if (RCAR_LSI == RCAR_S4)
    NOTICE("CA55 Loader Program Rev.%s\n", IPL_VERSION);
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
    NOTICE("CR52 Loader Program Rev.%s\n", IPL_VERSION);
#endif /* RCAR_LSI == RCAR_S4 */

    NOTICE("%s\n", build_message);

    /* Get PRR */
    reg = mem_read32(PRR);
    switch (reg & PRR_PRODUCT_MASK)
    {
        #if (RCAR_LSI == RCAR_S4)
        case PRR_PRODUCT_S4:
        {
            str = product_s4;
            break;
        }
        #elif (RCAR_LSI == RCAR_V4H)
        case PRR_PRODUCT_V4H:
        {
            str = product_v4h;
            break;
        }
        #elif (RCAR_LSI == RCAR_V4M)
        case PRR_PRODUCT_V4M:
        {
            str = product_v4m;
            break;
        }
        #endif /* RCAR_LSI == RCAR_S4 */
        default:
        {
            str = unknown;
            break;
        }
    }
    NOTICE("PRR is R-Car %s Ver.%d.%d\n", str,
        ((int)(reg & PRR_MAJOR_MASK) >> PRR_MAJOR_SHIFT)
        + PRR_MAJOR_OFFSET, (int)(reg & PRR_MINOR_MASK));

#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
    #if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
    /* Notice the ecc enable */
    NOTICE("Access Protection Enable\n");
    #endif /* ACC_PROT_ENABLE == PROTECTION_ENABLE */
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */
    store_time_checkpoint("init_done", 0);

/*****************************************************************************
 *  DDR Initialization
 *****************************************************************************/
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))

    /* DDR initialize */
    result = R_DRAM_Init();
    if (INITDRAM_OK != result)
    {
        ERROR("Failed to DRAM initialize (%d).\n", (int)result);
        panic;
    }

#if (ECM_ERROR_ENABLE == 1)
    ecm_error_enable();
#endif /* ECM_ERROR_ENABLE == 1 */

#if (ECC_ENABLE == 1)
    /* ECC Protection */
    ecc_sdram_enable();
#endif /* ECC_ENABLE == 1 */

    /* QoS configuration */
    qos_init();

    /* RT-VRAM Extend mode */
    rtvram_extendmode();

    /* memory copy */
    memcpy((void *)DISK_BUFFER_ADDR, (void *)DISK_BUFFER__IPL, 4096);
    memset((void *)DISK_BUFFER__IPL, 0xFF, 4096);
    memcpy((void *)AB_INFO_FLAG_ADDR, (void *)AB_INFO_FLAG__IPL, 4);
    memset((void *)AB_INFO_FLAG__IPL, 0xFF, 4);
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */
    store_time_checkpoint("DDR_and_Bus_init_done", 0);

/*****************************************************************************
 *  Load Certficate
 *****************************************************************************/

    /* Load content certificate */
    ca_load_num = mem_read32(CONTENT_CERT_DEST_ADDR);

    /* Get load information */
    load_init(li, ca_load_num);

#if (BOOT_MODE == SECURE)
/*****************************************************************************
 *  Check SecureBoot
 *****************************************************************************/
    secureboot_init();

    /* LCS judgement for secure boot */
    bootmode = judge_bootmode();

    if (NORMAL_BOOT != bootmode)
    {
        /* Content cert certification */
#if (BL2_LOAD_ENABLE == BL2_DISABLE)
        secureboot_verify(li, CA_OPTIONAL_ID, CA_OPTIONAL_ID + ca_load_num);
#else
        secureboot_verify(li, CA_BL2_ID, CA_BL2_ID + 1);
#endif
        store_time_checkpoint("verify_cert_done", 0);
    }
#endif /* BOOT_MODE == SECURE */

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
/*****************************************************************************
 *  Load RTOS#2
 *****************************************************************************/
    /* Start loading RTOS#2 image */
    load_image(&li[RTOS2_ID]);
    store_time_checkpoint("load_RTOS#2_done", li[RTOS2_ID].image_size);

    #if (BOOT_MODE == SECURE)
        /* Decryption image and Image cerfification */
        if (NORMAL_BOOT != bootmode)
        {
            secureboot_image(&li[RTOS2_ID], 1);
            store_time_checkpoint("verify_RTOS#2_done", 0);
        }
    #endif /* BOOT_MODE == SECURE */

    /* boot CR core2 */
    arm_cpu_on(RCAR_PWR_TARGET_CR, li[RTOS2_ID].boot_addr, 2);
    store_time_checkpoint("started_RTOS#2", 0);
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
/*****************************************************************************
 *  Load RTOS#0
 *****************************************************************************/
#define _IPL_END     (0xEB22FFF4)
#ifdef MOBIS_PRK3
    emmc_initialize();
    store_time_checkpoint("emmc_initialize", 0);
#if (BL2_LOAD_ENABLE == BL2_ENABLE)	/* do not clear eMMC */
    export_mmc_drv_obj();
#endif

    reg = mem_read32(AB_INFO_FLAG_ADDR);
    if (reg & AB_INFO_SELECT_2nd)
        slot = 1;
    // slot = ab_select_slot();
    load_update_part_num(li, ca_load_num, slot);
    NOTICE("slot: %d\n", slot);

    mem_write32(_IPL_END, 0x0);
#endif

    /* Start loading RTOS#0 image */
    load_image(&li[RTOS_ID]);
    store_time_checkpoint("load_RTOS#0_done", li[RTOS_ID].image_size);

    #if (BOOT_MODE == SECURE)
        /* Decryption image and Image cerfification */
        if (NORMAL_BOOT != bootmode)
        {
            /* WARNING! WARNING! WARNING! WARNING! */
            /* TODO: set 1 to panic! later */
            secureboot_image(&li[RTOS_ID], 0);
            store_time_checkpoint("verify_RTOS#0_done", 0);
        }
    #endif /* BOOT_MODE == SECURE */

    /* boot CR core0 */
    arm_cpu_on(RCAR_PWR_TARGET_CR, li[RTOS_ID].boot_addr, -1);

#ifdef MOBIS_PRK3
    /* enable CR-52 Core 2 */
    arm_cpu_on(RCAR_PWR_TARGET_CR, li[RTOS_ID].boot_addr, 2);
    store_time_checkpoint("started_RTOS#0", 0);
#endif
#if (BOOT_TIME_CHECK != 0)
    gpio_N1305(2);
#endif
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */

/*****************************************************************************
 *  Load CA Program#2--#8
 *****************************************************************************/
#if (BL2_LOAD_ENABLE == BL2_DISABLE)
    /* Start loading CA Program#n image */
    for (loop = 0U; loop < ca_load_num; loop++)
#else
    /* load bl2 */
    loop = (CA_BL2_ID - CA_OPTIONAL_ID);
#endif
    {
        /* Loading start */
        NOTICE("Loading %s...\n", li[CA_OPTIONAL_ID + loop].name);
        load_image(&li[CA_OPTIONAL_ID + loop]);
        store_time_checkpoint("load_CA_#_done", li[CA_OPTIONAL_ID + loop].image_size);

#if (BOOT_MODE == SECURE)
        /* Decryption image and Image certification  */
        if (NORMAL_BOOT != bootmode)
        {
            secureboot_image(&li[CA_OPTIONAL_ID + loop], 1);
            store_time_checkpoint("verify_CA_#_done", 0);
        }
#endif /* BOOT_MODE == SECURE */
    }

#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
    /* Set Secure Monitor parameter */
    #if (OPTEE_LOAD_ENABLE == OPTEE_DISABLE)
    smoni_set_param(li[CA_OPTIONAL_ID].boot_addr,        /* BL31 */
                    li[CA_OPTIONAL_ID + 1U].boot_addr);  /* U-Boot */
    #else
     #if (BL2_LOAD_ENABLE == BL2_DISABLE)	/* BL2 will load these */
    smoni_set_param(li[CA_OPTIONAL_ID].boot_addr,        /* BL31 */
                    li[CA_OPTIONAL_ID + 1U].boot_addr,   /* U-Boot */
                    li[CA_OPTIONAL_ID + 2U].boot_addr);  /* OP-TEE */
     #endif
    #endif /* OPTEE_LOAD_ENABLE == OPTEE_DISABLE */

    /* Before Boot CPU, Set the division ratio for CPU operating frequency */
    adj_ca_variant_freq();

/* boot CA */
#if (BL2_LOAD_ENABLE == BL2_DISABLE)
    arm_cpu_on(RCAR_PWR_TARGET_CA, li[CA_OPTIONAL_ID].boot_addr, -1);
#else	/* run BL2, not BL31 */
    arm_cpu_on(RCAR_PWR_TARGET_CA, li[CA_BL2_ID].boot_addr, -1);
#endif
    store_time_checkpoint("started_CA_core", 0);

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
/*****************************************************************************
 *  Load RTOS#1
 *****************************************************************************/
    /* Start loading RTOS#1 image */
    load_image(&li[RTOS1_ID]);
    store_time_checkpoint("load_RTOS#1_done", li[RTOS1_ID].image_size);

    #if (BOOT_MODE == SECURE)
        /* Decryption image and Image cerfification */
        if (NORMAL_BOOT != bootmode)
        {
            secureboot_image(&li[RTOS1_ID], 1);
            store_time_checkpoint("verify_RTOS#1_done", 0);
        }
    #endif /* BOOT_MODE == SECURE */

#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

    #if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
    sdram_protection(AXMM_DPTSECCR_NUM);
    #if (OPTEE_LOAD_ENABLE == OPTEE_ENABLE)
    sdram_protection(AXMM_DPTSECCR_NUM2);
    #endif /* OPTEE_LOAD_ENABLE == OPTEE_ENABLE */
    remove_rgid0_previlege();
    /*
     * SAN(Safety Application Note) 6.23.5 Operation
     * Checker processor :
     * Check RegionID/LifeC & memory area protection settings (including order & content of intermediate updates)
     * done by ICUMX.
     */
    rgid_protection_check();
    ram_protection_check();
    #endif /* ACC_PROT_ENABLE == PROTECTION_ENABLE */

    #if (BOOT_MODE == SECURE)
    if (NORMAL_BOOT != bootmode)
    {
        /* Compare Hash verified at ICUMX IPL (V4H only). (Target images are Secure FW and Cx 2nd IPL.) */
        /*
         * SAN(Safety Application Note) 6.23.5 Operation
         * Checker processor :
         * Re-do comparison of hash in Flash vs hash generated by ICUMX to confirm proper comparison.
         */
        final_hash_cmp();
        store_time_checkpoint("final_verify_done", 0);
    }
    #endif /* BOOT_MODE == SECURE */

    NOTICE("Load finish.(CR52 Loader)\n");

#elif (RCAR_LSI == RCAR_S4)
    #if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
    sdram_protection(AXMM_DPTSECCR_NUM);
    #endif /* ACC_PROT_ENABLE == PROTECTION_ENABLE */
    NOTICE("Load finish.(CA55 Loader)\n");
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */
    // ip_release();

    store_time_checkpoint("Cx_done_starting_RTOS#1", 0);
    // scmt_wait_ticks(SCMT_MS2TICKS(1000));
    print_time_checkpoints();
#if (BOOT_TIME_CHECK != 0)
    gpio_N1305(2);
#endif

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_1)
 #ifdef MOBIS_PRK3
    return li[RTOS_ID].boot_addr;
 #else
    return li[CA_OPTIONAL_ID].boot_addr;
 #endif
#elif (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
    return li[RTOS1_ID].boot_addr;
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */
}
/* End of function loader_main(void) */


#if (ACC_PROT_ENABLE == PROTECTION_ENABLE)
static void sdram_protection(uint32_t num)
{
    uint32_t val;
    uint32_t addr;

    /* Calculation of the address of the DPTSECCR register. */
    addr = (AXMM_DPTSECCR + (num * 4U));

    val = mem_read32(addr);
    val &= ~(AXMM_DPTSECCR_SECGRP_MASK | AXMM_DPTSECCR_SECGWP_MASK);
    val |= (AXMM_DPTSECCR_SECGRP_SEC | AXMM_DPTSECCR_SECGWP_SEC);
    mem_write32(addr, val);
}/* End of function void sdram_protection(void) */

#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
static void remove_rgid0_previlege(void)
{
    uint32_t val;
    uint32_t addr;

    /* Calculation of the address of the DPTRGNCR register. */
    addr = get_dptrgncr_addr(DPTRGNCR_PROTECT_AREA);

    val  = mem_read32(addr);
    val &= ~(AXMM_DPTRGNCR_RGN0RP_MASK | AXMM_DPTRGNCR_RGN0WP_MASK);
    val |= (AXMM_DPTRGNCR_RGN0RP| AXMM_DPTRGNCR_RGN0WP);    /* Remove RGID0 read/write previlege on SDRAM Area. */
    mem_write32(addr, val);

    /* Calculation of the address of the DPTRGNCR register. */
    addr = get_dptrgncr_addr(DPTRGNCR_LINUX_AREA);

    val  = mem_read32(addr);
    val &= ~(AXMM_DPTRGNCR_RGN0RP_MASK | AXMM_DPTRGNCR_RGN0WP_MASK);
    val |= (AXMM_DPTRGNCR_RGN0RP| AXMM_DPTRGNCR_RGN0WP);    /* Remove RGID0 read/write previlege on SDRAM Area. */
    mem_write32(addr, val);

    /* Calculation of the address of the SECCTRW0D_1 register. */
    addr = get_rtvram1_secctrwd_addr(SECCTRWD_AREA0);

    val  = mem_read32(addr);
    val &= ~(SECCTRWD_SAFG15WP_MASK);
    val |= SECCTRWD_SAFG15WP;   /* Remove RGID0/2 write previlege on RT-VRAM1 Area0. */
    mem_write32(addr, val);

    /* Calculation of the address of the SECCTRW2D_1 register. */
    addr = get_rtvram1_secctrwd_addr(SECCTRWD_AREA2);

    val  = mem_read32(addr);
    val &= ~(SECCTRWD_SAFG15WP_MASK);
    val |= SECCTRWD_SAFG15WP;   /* Remove RGID0/2 write previlege on RT-VRAM1 Area2. */
    mem_write32(addr, val);
}
/* End of function void remove_rgid0_previlege(void) */
#endif /* ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M)) */

#endif /* ACC_PROT_ENABLE == PROTECTION_ENABLE */
