/*******************************************************************************
* 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   : Image load function
 ******************************************************************************/
/******************************************************************************
 * @file          image_load.h
 * - Version      : 0.09
 * @brief         Access protection setting driver.
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 02.02.2022 0.01     First Release
 *         : 10.02.2022 0.02     Change the number of CA programs
 *         : 17.02.2022 0.03     Support AArch32
 *         : 18.05.2022 0.04     Integrated LOAD_INFO
 *                               Defined value integration
 *                               Remove unused define values
 *                               Changed to processing for each device
 *                               Change structure member name
 *                               Remove LOGICAL_CONTENT_CERT_ADDR
 *                               Add get_logic_cont_cert_addr
 *                               Change the argument type of get_src_addr_offset_in_cert
 *                               Added argument check
 *                               Remove unnecessary macros
 *                               Add argument of load_init()
 *                               Change for memory map update
 *         : 16.06.2022 0.05     Change log output
 *                               Support secure boot for S4
 *         : 31.10.2022 0.06     License notation change.
 *         : 21.08.2023 0.07     Add support for V4M.
 *         : 19.12.2024 0.08     Add definitions for RTOS#1 and RTOS#2.
 *         : 26.05.2025 0.09     Change address and size of CA program2.
 *****************************************************************************/

#ifndef LOAD_IMAGE_H_
#define LOAD_IMAGE_H_

#include "log.h"

/* define */
/* For Build Option RTOS_LOAD_NUM */
#define RTOS_LOAD_NUM_1     (1U)    /* RTOS is RTOS#0 only. */
#define RTOS_LOAD_NUM_3     (3U)    /* RTOS are RTOS#0, RTOS#1, and RTOS#2. */

/* For Build Option OPTEE_LOAD_ENABLE */
#define OPTEE_DISABLE       (0U)    /* Load OP-TEE image disable. */
#define OPTEE_ENABLE        (1U)    /* Load OP-TEE image enable. */

/* DRAM address */
#define DRAM_BASE       (0x40000000U)
#define DRAM_SIZE       (0x80000000U)
#define DRAM_END        ((DRAM_BASE + DRAM_SIZE) - 1U)

/* RT-SRAM */
/* S4:RT-SRAM V4H/V4M:RT-VRAM0 Mirror */
#define RTSRAM_BASE     (0xEB200000U)
#define RTSRAM_SIZE     ((1024U - 16U) * 1024U) /* 1MB - 16KB(stack size) */
#define RTSRAM_END      ((RTSRAM_BASE + RTSRAM_SIZE) - 1U)

/* RT-VRAM */
/* S4:RT-VRAM V4H/V4M:RT-VRAM1 */
#define RTVRAM_BASE     (0xE2000000U)
#define RTVRAM_SIZE     (1024U * 1024U)     /* 1MB */
#define RTVRAM_VBUF_28M         (28U)       /* 28MB */
#define RTVRAM_VBUF_SIZE        ((RTVRAM_VBUF_28M - 1U) * 1024U * 1024U)   /* 3MB to 27MB (The first 1MB is actual RAM.) */
#define RTVRAM_VBUF_TOP         (RTVRAM_BASE + RTVRAM_SIZE)   /* 0xE2100000 */
#define RTVRAM_VBUF_END         ((RTVRAM_VBUF_TOP + RTVRAM_VBUF_SIZE) - 1U)
#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
#define RTVRAM_8WAY_28M_SRAM_SIZE   (0x00010000U)   /* 64KiB */
#define RTVRAM_SRAM_TOP         (RTVRAM_BASE)
#define RTVRAM_SRAM_END         (RTVRAM_SRAM_TOP + RTVRAM_8WAY_28M_SRAM_SIZE - 1U)  /* 0xE2000000 - 0xE200FFFF */
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

/* System RAM */
#define SYSRAM_BASE (0xE6300000U)
#if (RCAR_LSI == RCAR_S4)
#define SYSRAM_SIZE (384U * 1024U)   /* 384KB */
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#define SYSRAM_SIZE (1024U * 1024U)  /* 1MB */
#endif /* RCAR_LSI == RCAR_S4 */
#define SYSRAM_END  ((SYSRAM_BASE + SYSRAM_SIZE) - 1U)

/* Cx Loader */
#define IPL_TOP         (0xE6300000U)
#define IPL_SIZE        (0x00030000U) /* 192KiB */
#define IPL_END         ((IPL_TOP +IPL_SIZE) - 1U)

/* Certificate size */
#define CONTENT_CERT_OFFSET         (0x00006000U)   /* certificate top offset */
#define CONTENT_CERT_INFO_SIZE      (0x00001000U)   /* Content cert header area size(4KiB) */
#define CONTENT_CERT_DST_SIZE       (0x00000800U)   /* content cert dst size */
#define KEY_CERT_SIZE               (0x00002000U)   /* Key cert area size(8KiB) */

/* Load ID */
#define RTOS_ID             (1U)
#define CA_PROGRAM_ID       (2U)
#define CA_OPTIONAL_ID      (6U)
#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
#define RTOS1_ID            (16U)   /* 16:RTOS#1 */
#define RTOS2_ID            (17U)   /* 17:RTOS#2 */
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

/* Number of Max loading image */
#define CA_MAX_IMAGE        (8U)        /* CA Load program MAX image num */
#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_1)
#define MAX_PLACED          (16U)       /* Load program MAX image num */
#elif (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
#define MAX_PLACED          (18U)       /* Load program MAX image num */
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_1 */

#define TARGET_MEM_DRAM     (0U)
#define TARGET_MEM_RTSRAM   (1U)
#define TARGET_MEM_RTVRAM   (2U)
#define TARGET_MEM_SYSRAM   (3U)
#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
#define TARGET_MEM_SRAM_IN_RTVRAM  (4U)
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */

/* get info from cert address offset */
#define CERT_INFO_SIZE_OFFSET   (0x00000264U)   /* Offset Type1 */
#define CERT_INFO_DST_OFFSET    (0x00000154U)   /* Offset Type1 */
#define CERT_INFO_SIZE_OFFSET1  (0x00000364U)   /* Offset Type2 */
#define CERT_INFO_DST_OFFSET1   (0x000001D4U)   /* Offset Type2 */
#define CERT_INFO_SIZE_OFFSET2  (0x00000464U)   /* Offset Type2 */
#define CERT_INFO_DST_OFFSET2   (0x00000254U)   /* Offset Type2 */

/* Certificate logical address */
#define CONTENT_CERT_DEST_ADDR    (0xEB230000U)

/* BL31/BL32 check */
/* check image num */
#if (OPTEE_LOAD_ENABLE == OPTEE_DISABLE)
#define CA_IMAGESIZECHK_DEF (2U)
#else
#define CA_IMAGESIZECHK_DEF (3U)
#endif /* OPTEE_LOAD_ENABLE == OPTEE_DISABLE */
/* load_id */
#define CA_PROGRAM1_ID      (6U)
#define CA_PROGRAM2_ID      (7U)
#if (OPTEE_LOAD_ENABLE == OPTEE_ENABLE)
#define CA_PROGRAM3_ID      (8U)
#endif /* OPTEE_LOAD_ENABLE == OPTEE_ENABLE */

#define CA_PROGRAM1_ADR     (0x46400000U)
#define CA_PROGRAM1_SIZE    (0x00022000U)
#if (RCAR_LSI == RCAR_S4)
#define CA_PROGRAM2_ADR     (0x44100000U)
#define CA_PROGRAM2_SIZE    (0x00100000U)
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
#define CA_PROGRAM2_ADR     (0x00000000U)
#define CA_PROGRAM2_SIZE    (0x00000000U)
#endif /* RCAR_LSI == RCAR_S4 */
#if (OPTEE_LOAD_ENABLE == OPTEE_ENABLE)
#define CA_PROGRAM3_ADR     (0x44100000U)
#define CA_PROGRAM3_SIZE    (0x00100000U)
#endif /* OPTEE_LOAD_ENABLE == OPTEE_ENABLE */

/* key cert address */
#define TFMV_KEY_CERT_ADDR  (CONTENT_CERT_DEST_ADDR + CONTENT_CERT_INFO_SIZE) /* 0xEB231000 */
#define NTFMV_KEY_CERT_ADDR (TFMV_KEY_CERT_ADDR + KEY_CERT_SIZE)              /* 0xEB233000 */

/* struct */
/* load image range */
typedef struct {
    uint32_t load_id;
    uint32_t image_adr;
    uint32_t image_size;
} IMAGE_RANGE;

/* load address range */
typedef struct {
    uint32_t    cx_topadd;
    uint32_t    cx_endadd;
} ADDRESS_RANGE;

/* load info */
typedef struct{
    const char *name;       /* store load image name */
    uint32_t image_size;    /* store image size */
    uint32_t boot_addr;     /* store boot address of image */
    uint32_t key_cert_addr; /* store key cert address */
    uint32_t cnt_cert_addr; /* store content cert address */
    uint32_t src_addr;      /* store source address */
    uint32_t part_num;      /* store eMMC partition number */
    uint32_t load_id;       /* store Load ID */
    uint32_t cmac[4U];      /* store cmac */

} LOAD_INFO;

static inline uint32_t get_src_addr_offset_in_cert(uint32_t id)
{
    /* INT30-C Pre confirmation */
    if (id > UINT32_MAX / 0x10U)
    {
        ERROR("get_src_addr_offset_in_cert id error.\n");
        panic;
    }

    return (CONTENT_CERT_DEST_ADDR + ((id * 0x10U) + 0x8U));
}

static inline uint32_t get_logic_cont_cert_addr(uint32_t num)
{
    /* INT30-C Pre confirmation */
    if (num > UINT32_MAX / 0x10U)
    {
        ERROR("get_logic_cont_cert_addr num error.\n");
        panic;
    }
    return (CONTENT_CERT_DEST_ADDR + CONTENT_CERT_OFFSET + (num * CONTENT_CERT_DST_SIZE));
}

/* Prototype */
void load_image(LOAD_INFO* li);
void load_init(LOAD_INFO* li, uint32_t num);
void load_start(LOAD_INFO* li);
#endif /* LOAD_IMAGE_H_ */

