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

/*******************************************************************************
 * DESCRIPTION   : Image load function header
 ******************************************************************************/

#ifndef LOAD_IMAGE_H_
#define LOAD_IMAGE_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. */

/* ICUMX Loader */
#define IPL_TOP         (0xEB210000U)
#define IPL_SIZE        (128U * 1024U)
#define IPL_END         ((IPL_TOP +IPL_SIZE) - 1U)

#define MCU_OFFSET              (0x0200U)   /* 512byte */

/* Certificate logical address */
extern char __ghsbegin_sa9_load[];
#define SA9_DEST_ADDR  (uintptr_t)(&__ghsbegin_sa9_load[0])
#define CONTENT_CERT_OFFSET (0x6000U)

/* key cert address */
#define TFMV_KEY_CERT_ADDR  (SA9_DEST_ADDR + CONTENT_CERT_INFO_SIZE) /* 0xFDE31000 */
#define NTFMV_KEY_CERT_ADDR (TFMV_KEY_CERT_ADDR + KEY_CERT_SIZE)     /* 0xFDE33000 */

/* Size of each content contained in SA9. */
#define KEY_CERT_SIZE           (0x00002000U) /* Key cert size(8KiB)             */
#define CONTENT_CERT_INFO_SIZE  (0x00001000U) /* Content cert header size(4KiB)  */
#define CONTENT_CERT_SIZE       (0x00000800U) /* content cert src size(2KiB)     */
#define MIN_VER_TBL_SIZE        (0x00001000U) /* Software minimum version table  */

/* Load ID */
#define SECURE_FW_ID                (0U)    /*  0:Secure Firmware */
#define RTOS_ID                     (1U)    /*  1:RTOS#0 */
#define CA_PROGRAM_ID               (2U)    /*  2:CX 2nd IPL */
#define ICUMH_PROGRAM_ID            (3U)    /*  3:ICUMH program */
#define G4MH_PROGRAM_ID             (4U)    /*  4:G4MH program(1st) 5:G4MH program(2nd) */
#define CA_OPTIONAL_ID              (6U)    /*  6:CA Program#1, 7:CA Program#2 ... 13:CA Program#8 */
#define TFMV_MIN_VER_TBL_ID         (14U)   /* 14:TFMV Software minimum version table */
#define NTFMV_MIN_VER_TBL_ID        (15U)   /* 15:NTFMV Software minimum version table */
#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 NUM_OF_ALWAYS_LOAD_CERT (6U)  /* Secure FW + RTOS + Cx IPL + ICUMH + (G4MH * 2) */
#define CA_MAX_IMAGE            (8U)  /* CA program MAX image num */

#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_1)
#define MAX_PLACED              (16U) /* IPL (or minimum version table) + Secure FW + RTOS *
                                       * + Cx IPL + (CA program * 8) + ICUMH + G4MH        */
#elif (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
#define MAX_PLACED              (18U) /* IPL (or minimum version table) + Secure FW + RTOS#0          *
                                       * + Cx IPL + (CA program * 8) + ICUMH + G4MH + RTOS#1 + RTOS#2 */
#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)
#define TARGET_MEM_CODESRAM (4U)

/* 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 */

#define FLASH_BOOT  (0U)
#define EMMC_BOOT  (1U)

#define CERT_INFO_FLG_OFFSET    (0x0000000CU)
#define KEY_SIZE_BIT_SHIFT      (21U)

/* Parameter info of secure data (for ICUM FW) */
#define SECUREDATA_SIZE     (112U * 1024U)  /* 112KB */

/* struct */
/* load address range */
typedef struct {
    uint32_t    topadd;
    uint32_t    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 image_id;      /* store image ID */
} LOAD_INFO;

static inline uint32_t get_src_addr_offset_in_cert(uint32_t id)
{
    return (SA9_DEST_ADDR + ((id * 0x10U) + 0x8U));
}

static inline uint32_t get_logic_cont_cert_addr(uint32_t num)
{
    return (SA9_DEST_ADDR + CONTENT_CERT_OFFSET + (num * CONTENT_CERT_SIZE));
}

/* Prototype */
uint32_t load_content_cert(void);
void load_image(LOAD_INFO* li);
void load_init(LOAD_INFO* li);
void check_load_area(const LOAD_INFO* li);
void load_start(const LOAD_INFO* li);
void load_end(void);
void check_overflow(uint32_t addr, uint32_t len, uint32_t *end_addr, const char *func_name);
void load_securedata(uint32_t target_id);
#endif /* LOAD_IMAGE_H_ */

