/*******************************************************************************
 * 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 2021-2024 Renesas Electronics Corporation All rights reserved.
 *******************************************************************************/

/*******************************************************************************
 * DESCRIPTION   : Image load for Flash function
 ******************************************************************************/
/******************************************************************************
 * @file          image_load_flash.c
 * - Version      : 0.04
 * @brief         Image load for Flash function.
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 30.09.2021 0.01     First Release
 *         : 23.05.2022 0.02     Support for updating the memory map.
 *         : 05.08.2022 0.03     Add load_ver_tbl_cert_for_flash function.
 *         : 20.12.2024 0.04     Add support for booting CR52 3 cores.
 *****************************************************************************/

/* indelude */
#include <stdint.h>
#include <image_load_flash.h>
#include <dma.h>
#include <remap.h>
#include <mem_io.h>
#include <rom_api.h>
#include "image_load.h"

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
static void load_rtos12_cert_for_flash(void);
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

static void load_ver_tbl_cert_for_flash(int slot);

uint32_t load_content_cert_for_flash(int slot)
{
    uint32_t load_num;
    uint32_t phys_dst;
    uint32_t phys_src;
    uint32_t size;

    /* source address.(0x08240000) */
    phys_src = FLASH_CONTENT_CERT_ADDR + (slot * CONTENT_CERT_2nd_OFFSET);
    /* Get physical address of transfer destination. */
    phys_dst = remap_get_phys_addr(SA9_DEST_ADDR);
    /* transfer size */
    size = CONTENT_CERT_INFO_SIZE;
    /* Load content cert header */
    dma_trans_start(phys_dst, phys_src, size);

    NOTICE(
        "======== content cert info ========\n"
        "destination address:0x%08x\n"
        "physical destination address:0x%08x\n"
        "source address:0x%08x\n"
        "size:0x%08x\n", SA9_DEST_ADDR, phys_dst, phys_src, size);


    /* End loading cert header */
    load_end();

    load_num = mem_read32(SA9_DEST_ADDR);


    /* Check number of image load.
       In case of number of image load is 0, error of transfer parameter.
       In case of number of image loads is higher than 8,
       the transfer parameter error.                */
    if ((load_num == 0U) || (load_num > CA_MAX_IMAGE))
    {
        ERROR("Content cert info 'load image num' fault.\n");
        ERROR("load image num = %d\n",load_num);
        panic;
    }

    /* Increase forwarding address by the size of cert header */
    phys_src += CONTENT_CERT_INFO_SIZE;
    phys_dst += CONTENT_CERT_INFO_SIZE;

    /* Transfer size calculation for SA9                                                          *
     * TFMV key + NTFMV key + TFMV/NTFMV minimum version table + (content cert * number of loads) */
    size = ((KEY_CERT_SIZE * 2U) + MIN_VER_TBL_SIZE
             + ((NUM_OF_ALWAYS_LOAD_CERT + load_num) * CONTENT_CERT_SIZE));

    /* Load SA9. */
    dma_trans_start(phys_dst, phys_src, size);

    /* End loading content cert */
    load_end();

    NOTICE("======== content of SA9 ========\n"
            "address:0x%08x size:0x%08x\n", phys_dst, size);

    /* Load content cert of Software minimum version table */
    load_ver_tbl_cert_for_flash(slot);

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
    /* Load content cert of RTOS#1 and RTOS#2 */
    load_rtos12_cert_for_flash();
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

    return load_num;
}
/* End of function load_content_cert_for_flash(void) */

static void load_ver_tbl_cert_for_flash(int slot)
{
#if (SW_VERSION_CHECK == OPT_VERSION_CHECK_ENABLE)
    uint32_t phys_dst;
    uint32_t phys_src;
    uint32_t size;

    /* Source address.(0x0824D000) */
    phys_src = FLASH_VER_TBL_CNT_CERT_ADDR + (slot * CONTENT_CERT_2nd_OFFSET);
    /* Get physical address of transfer destination. */
    phys_dst = remap_get_phys_addr(SA9_DEST_ADDR + VER_TBL_CNT_CERT_OFFSET);
    /* transfer size */
    size = CONTENT_CERT_SIZE * 2U;

    /* Load content cert of Software minimum version table. */
    dma_trans_start(phys_dst, phys_src, size);

    /* End loading content cert */
    load_end();

    NOTICE("======== content cert of SW version table ========\n"
            "address:0x%08x size:0x%08x\n", phys_dst, size);

#endif /* (SW_VERSION_CHECK == OPT_VERSION_CHECK_ENABLE) */
}
/* End of function load_ver_tbl_cert_for_flash(void) */

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
static void load_rtos12_cert_for_flash(void)
{
    uint32_t phys_dst;
    uint32_t phys_src;
    uint32_t size;

    /* Source address.(0x0824E000) */
    phys_src = FLASH_RTOS12_CNT_CERT_ADDR;
    /* Get physical address of transfer destination. */
    phys_dst = remap_get_phys_addr(SA9_DEST_ADDR + RTOS12_CNT_CERT_OFFSET);
    /* transfer size */
    size = CONTENT_CERT_SIZE * 2U;  /* RTOS#1 and RTOS#2 */

    /* Load content cert of Software minimum version table. */
    dma_trans_start(phys_dst, phys_src, size);

    /* End loading content cert */
    load_end();

    NOTICE("======== content cert of RTOS#1 and RTOS#2 ========\n"
            "address:0x%08x size:0x%08x\n", phys_dst, size);

}
/* End of function load_rtos12_cert_for_flash(void) */
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

