/******************************************************************************/
/* Component Name   ICU-M COMM(PE) Driver                                     */
/******************************************************************************/
/* Product      : ICU-M Firmware                                              */
/******************************************************************************/
/*******************************************************************************
* Copyright(C) 2021-2023 Renesas Electronics Corporation.                       
*                                                                               
*          RENESAS ELECTRONICS CONFIDENTIAL AND PROPRIETARY                     
*                                                                               
* These instructions, statements, and programs are the confidential information 
* of Renesas Electronics Corporation. They must be used and modified solely for 
* the purpose for which it was furnished by Renesas Electronics Corporation.    
* All part of them must not be reproduced nor disclosed to others in any form,  
* without the prior written permission of Renesas Electronics Corporation.      
*******************************************************************************/

#if !defined(ICUM_D_COMM_PE_H)
#define ICUM_D_COMM_PE_H

/**************************************************************************************/
/* Global Pointer Variable                                                            */
/**************************************************************************************/

/*====================================================================================*/
/* Shared RAM area address                                                            */
/*====================================================================================*/
extern uint8_t  __ghsbegin_start_gRAM_BANK_A[];         /* Start address ( Bank_A )   */
extern uint8_t  __ghsbegin_end_gRAM_BANK_A[];           /* End address + 1 ( Bank_A ) */

extern uint8_t  __ghsbegin_start_gRAM_MEV[];            /* Start addr ( Exclusion )   */

/**************************************************************************************/
/* Definition                                                                         */
/**************************************************************************************/

/* ICUMD Command Register */
#define ICUM_CMDREGICUM_ICU2PES0        (*(volatile uint32_t*)0xE6610010U)
#define ICUM_CMDREGICUM_ICU2PES1        (*(volatile uint32_t*)0xE6610128U)
#define ICUM_CMDREGICUM_ICU2PES2        (*(volatile uint32_t*)0xE6610158U)
#define ICUM_CMDREGICUM_ICU2PES3        (*(volatile uint32_t*)0xE6610188U)
#define ICUM_CMDREGICUM_ICU2PES4        (*(volatile uint32_t*)0xE66101B8U)
#define ICUM_CMDREGICUM_ICU2PES5        (*(volatile uint32_t*)0xE66101E8U)
#define ICUM_CMDREGICUM_ICU2PES6        (*(volatile uint32_t*)0xE6610218U)
#define ICUM_CMDREGICUM_ICU2PES7        (*(volatile uint32_t*)0xE6610248U)
#define ICUM_CMDREGICUM_ICU2PES8        (*(volatile uint32_t*)0xE6610278U)
#define ICUM_CMDREGICUM_PE2ICUS0        (*(volatile uint32_t*)0xE6610014U)
#define ICUM_CMDREGICUM_PE2ICUS1        (*(volatile uint32_t*)0xE661012CU)
#define ICUM_CMDREGICUM_PE2ICUS2        (*(volatile uint32_t*)0xE661015CU)
#define ICUM_CMDREGICUM_PE2ICUS3        (*(volatile uint32_t*)0xE661018CU)
#define ICUM_CMDREGICUM_PE2ICUS4        (*(volatile uint32_t*)0xE66101BCU)
#define ICUM_CMDREGICUM_PE2ICUS5        (*(volatile uint32_t*)0xE66101ECU)
#define ICUM_CMDREGICUM_PE2ICUS6        (*(volatile uint32_t*)0xE661021CU)
#define ICUM_CMDREGICUM_PE2ICUS7        (*(volatile uint32_t*)0xE661024CU)
#define ICUM_CMDREGICUM_PE2ICUS8        (*(volatile uint32_t*)0xE661027CU)
#define ICUM_CMDREGICUM_PE2ICUFS0       (*(volatile uint32_t*)0xE6610044U)
#define ICUM_CMDREGICUM_PE2ICUFS1       (*(volatile uint32_t*)0xE6610104U)
#define ICUM_CMDREGICUM_PE2ICUFS2       (*(volatile uint32_t*)0xE6610134U)
#define ICUM_CMDREGICUM_PE2ICUFS3       (*(volatile uint32_t*)0xE6610164U)
#define ICUM_CMDREGICUM_PE2ICUFS4       (*(volatile uint32_t*)0xE6610194U)
#define ICUM_CMDREGICUM_PE2ICUFS5       (*(volatile uint32_t*)0xE66101C4U)
#define ICUM_CMDREGICUM_PE2ICUFS6       (*(volatile uint32_t*)0xE66101F4U)
#define ICUM_CMDREGICUM_PE2ICUFS7       (*(volatile uint32_t*)0xE6610224U)
#define ICUM_CMDREGICUM_PE2ICUFS8       (*(volatile uint32_t*)0xE6610254U)
#define ICUM_CMDREGICUM_PE2ICUIE0       (*(volatile uint32_t*)0xE661004CU)
#define ICUM_CMDREGICUM_PE2ICUIE1       (*(volatile uint32_t*)0xE661010CU)
#define ICUM_CMDREGICUM_PE2ICUIE2       (*(volatile uint32_t*)0xE661013CU)
#define ICUM_CMDREGICUM_PE2ICUIE3       (*(volatile uint32_t*)0xE661016CU)
#define ICUM_CMDREGICUM_PE2ICUIE4       (*(volatile uint32_t*)0xE661019CU)
#define ICUM_CMDREGICUM_PE2ICUIE5       (*(volatile uint32_t*)0xE66101CCU)
#define ICUM_CMDREGICUM_PE2ICUIE6       (*(volatile uint32_t*)0xE66101FCU)
#define ICUM_CMDREGICUM_PE2ICUIE7       (*(volatile uint32_t*)0xE661022CU)
#define ICUM_CMDREGICUM_PE2ICUIE8       (*(volatile uint32_t*)0xE661025CU)
#define ICUM_CMDREGICUM_ICU2PEF0        (*(volatile uint32_t*)0xE6610050U)
#define ICUM_CMDREGICUM_ICU2PEF1        (*(volatile uint32_t*)0xE6610110U)
#define ICUM_CMDREGICUM_ICU2PEF2        (*(volatile uint32_t*)0xE6610140U)
#define ICUM_CMDREGICUM_ICU2PEF3        (*(volatile uint32_t*)0xE6610170U)
#define ICUM_CMDREGICUM_ICU2PEF4        (*(volatile uint32_t*)0xE66101A0U)
#define ICUM_CMDREGICUM_ICU2PEF5        (*(volatile uint32_t*)0xE66101D0U)
#define ICUM_CMDREGICUM_ICU2PEF6        (*(volatile uint32_t*)0xE6610200U)
#define ICUM_CMDREGICUM_ICU2PEF7        (*(volatile uint32_t*)0xE6610230U)
#define ICUM_CMDREGICUM_ICU2PEF8        (*(volatile uint32_t*)0xE6610260U)
#define ICUM_CMDREGICUM_ICU2PEFC0       (*(volatile uint32_t*)0xE6610058U)
#define ICUM_CMDREGICUM_ICU2PEFC1       (*(volatile uint32_t*)0xE6610118U)
#define ICUM_CMDREGICUM_ICU2PEFC2       (*(volatile uint32_t*)0xE6610148U)
#define ICUM_CMDREGICUM_ICU2PEFC3       (*(volatile uint32_t*)0xE6610178U)
#define ICUM_CMDREGICUM_ICU2PEFC4       (*(volatile uint32_t*)0xE66101A8U)
#define ICUM_CMDREGICUM_ICU2PEFC5       (*(volatile uint32_t*)0xE66101D8U)
#define ICUM_CMDREGICUM_ICU2PEFC6       (*(volatile uint32_t*)0xE6610208U)
#define ICUM_CMDREGICUM_ICU2PEFC7       (*(volatile uint32_t*)0xE6610238U)
#define ICUM_CMDREGICUM_ICU2PEFC8       (*(volatile uint32_t*)0xE6610268U)
#define ICUM_CMDREGICUM_ICU2PEIE0       (*(volatile uint32_t*)0xE661005CU)
#define ICUM_CMDREGICUM_ICU2PEIE1       (*(volatile uint32_t*)0xE661011CU)
#define ICUM_CMDREGICUM_ICU2PEIE2       (*(volatile uint32_t*)0xE661014CU)
#define ICUM_CMDREGICUM_ICU2PEIE3       (*(volatile uint32_t*)0xE661017CU)
#define ICUM_CMDREGICUM_ICU2PEIE4       (*(volatile uint32_t*)0xE66101ACU)
#define ICUM_CMDREGICUM_ICU2PEIE5       (*(volatile uint32_t*)0xE66101DCU)
#define ICUM_CMDREGICUM_ICU2PEIE6       (*(volatile uint32_t*)0xE661020CU)
#define ICUM_CMDREGICUM_ICU2PEIE7       (*(volatile uint32_t*)0xE661023CU)
#define ICUM_CMDREGICUM_ICU2PEIE8       (*(volatile uint32_t*)0xE661026CU)
#define ICUM_CMDREGICUM_ICU2PEIS0       (*(volatile uint32_t*)0xE6610060U)
#define ICUM_CMDREGICUM_ICU2PEIS1       (*(volatile uint32_t*)0xE6610120U)
#define ICUM_CMDREGICUM_ICU2PEIS2       (*(volatile uint32_t*)0xE6610150U)
#define ICUM_CMDREGICUM_ICU2PEIS3       (*(volatile uint32_t*)0xE6610180U)
#define ICUM_CMDREGICUM_ICU2PEIS4       (*(volatile uint32_t*)0xE66101B0U)
#define ICUM_CMDREGICUM_ICU2PEIS5       (*(volatile uint32_t*)0xE66101E0U)
#define ICUM_CMDREGICUM_ICU2PEIS6       (*(volatile uint32_t*)0xE6610210U)
#define ICUM_CMDREGICUM_ICU2PEIS7       (*(volatile uint32_t*)0xE6610240U)
#define ICUM_CMDREGICUM_ICU2PEIS8       (*(volatile uint32_t*)0xE6610270U)
#define ICUM_CMDREGICUM_PE2ICUSFS       (*(volatile uint32_t*)0xE6610074U)
#define ICUM_CMDREGICUM_SEMAPE00        (*(volatile uint32_t*)0xE66100A0U)
#define ICUM_CMDREGICUM_SEMAPE01        (*(volatile uint32_t*)0xE66100A4U)
#define ICUM_CMDREGICUM_SEMAPE02        (*(volatile uint32_t*)0xE66100A8U)
#define ICUM_CMDREGICUM_SEMAPE03        (*(volatile uint32_t*)0xE66100ACU)
#define ICUM_CMDREGICUM_SEMAPE04        (*(volatile uint32_t*)0xE66100B0U)
#define ICUM_CMDREGICUM_SEMAPE05        (*(volatile uint32_t*)0xE66100B4U)
#define ICUM_CMDREGICUM_SEMAPE06        (*(volatile uint32_t*)0xE66100B8U)
#define ICUM_CMDREGICUM_SEMAPE07        (*(volatile uint32_t*)0xE66100BCU)
#define ICUM_CMDREGICUM_SEMAPE08        (*(volatile uint32_t*)0xE66100C0U)
#define ICUM_CMDREGICUM_SEMAPE0A        (*(volatile uint32_t*)0xE66100C8U)
#define ICUM_CMDREGICUM_SEMAPE0B        (*(volatile uint32_t*)0xE66100CCU)
#define ICUM_CMDREGICUM_SEMAPE0C        (*(volatile uint32_t*)0xE66100D0U)
#define ICUM_CMDREGICUM_SEMAPE0D        (*(volatile uint32_t*)0xE66100D4U)
#define ICUM_CMDREGICUM_SEMAPE0E        (*(volatile uint32_t*)0xE66100D8U)
#define ICUM_CMDREGICUM_SEMAPE0F        (*(volatile uint32_t*)0xE66100DCU)
#define ICUM_CMDREGICUM_SEMAPE10        (*(volatile uint32_t*)0xE66100E0U)
#define ICUM_CMDREGICUM_SEMAPE11        (*(volatile uint32_t*)0xE66100E4U)
#define ICUM_CMDREGICUM_SEMAPE12        (*(volatile uint32_t*)0xE66100E8U)

/* Bit position of initialization process execution state ( INIT_PROCESS_TYPE ) */
#define PE_QUE_INIT                     (0U)       /* PE queue init                  */
#define PE_INTC_INIT                    (4U)       /* PE INTC initialization         */
#define PE_ICU2PEI_INIT                 (8U)       /* PE ICU2PEI initialization      */

/* Execution state of initialization process ( INIT_PROCESS_STATUS ) */
#define INIT_UNPROCESSED                (0U)
#define INIT_PROCESSED                  (1U)

/* Mask pattern of service queue address ( QUE_ADDR_MASK_PATTERN ) */
#define QUE_ADDR_LOWER_24BITS           (0x00FFFFFFU)
#define QUE_ADDR_UPPER_8BITS_VALUE      (0xFF000000U)

/* Destination PE set value of INTICUP interrupt ( INTICUP_PESEL_PATTERN ) */
#define INTICUP_PESEL_TO_PE0            (0x00000000U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE1            (0x00000001U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE2            (0x00000002U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE3            (0x00000003U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE4            (0x00000004U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE5            (0x00000006U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE6            (0x00000007U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE7            (0x00000008U)    /* Set value (bit 3-0)      */
#define INTICUP_PESEL_TO_PE8            (0x00000009U)    /* Set value (bit 3-0)      */
/* Mask pattern for non set PESELs */
#define INTICUP_ICH_MASK                (0xFFFFFFF8U)

/* Bit position of INTICUP interrupt each PE ( INTICUP_BIT_POSITION ) */
#define INTICUP_EACH_PE_BIT_WIDTH       (3U)

/* PE Identifier value ( PEID_VALUE ) */
#define PEID_PE0                        (0U)
#define PEID_PE1                        (1U)
#define PEID_PE2                        (2U)
#define PEID_PE3                        (3U)

#define PEID_MASK                       (0x000000FU)
/* Bit position of PE status information ( PE2ICUS_BIT_POSITION ) */
#define INFO_PE_ST_POSITION             (24U)

/* Bit pattern of PE status information ( INFO_PE_ST_BIT_PATTERN ) */
#define INFO_PE_ST_FACIACCDIS_BIT       (0x00000001U)
#define INFO_PE_ST_FLS_OPRN_BIT         (0x00000001U)
#define INFO_PE_ST_FLS_DF_PRG_BIT       (0x00000001U)
#define INFO_PE_ST_FLS_CF_PRG_BIT       (0x00000001U)

/* Section address information ( SECTION_ADDRESS_INFO ) */
#define ADDR_START_SHARED_RAM           ((uint32_t *)((void *)__ghsbegin_start_gRAM_BANK_A))
#define ADDR_END_PLUS1_SHARED_RAM       ((uint32_t *)((void *)__ghsbegin_end_gRAM_BANK_A))

#define PE_SEMAPHORE_RES              (0x01000000U)
#define PE_SEMAPHORE_REQ              (0x02000000U)
#define PE_SEMAPHORE_ERR              (0x20000000U)
#define PE_SEMAPHORE_AUTH_MASK        (0xC0000000U)
#define PE_SEMAPHORE_AUTH_FREE        (0x00000000U)

#define PE_SEMAPHORE_AUTH_GET1ST      (0x00000000U)
#define PE_SEMAPHORE_AUTH_GET2ND      (0x80000000U)
#define PE_SEMAPHORE_WAIT             (0x0002645CU)

#define PE_SEMAPHORE_ER_SYSTEM        (0x00000001U)
#define PE_SEMAPHORE_ER_TIMEOUT       (0x00000002U)

#define PE_SEMAPHORE_ON               (0x01U)
#define PE_SEMAPHORE_OFF              (0x00U)

#define PE_SECURE_MODE_PE0              (0x00000001U)
#define PE_SECURE_MODE_PE5              (0x00000002U)
#define PE_SECURE_MODE_PE6              (0x00000004U)
#define PE_SECURE_MODE_PE1              (0x00000008U)
#define PE_SECURE_MODE_PE2              (0x00000010U)
#define PE_SECURE_MODE_PE3              (0x00000020U)
#define PE_SECURE_MODE_PE4              (0x00000040U)
#define PE_SECURE_MODE_PE7              (0x00000080U)
#define PE_SECURE_MODE_PE8              (0x00000100U)
#define PE_SECURE_MODE_BITOFF           (0U)

#define QUEUE_INDEX_FIRST               (0x00U)
#define QUEUE_INDEX_MAX                 (0xFFU)

/* Size of service queue area ( SERVICE_QUEUE_AREA_SIZE ) */
#define SERV_REQUEST_QUEUE_AREA_SIZE    (64U)
#define SERV_RESPONSE_QUEUE_AREA_SIZE   (64U)

#define TOTAL_SERVICE_QUEUE_AREA_SIZE   (SERV_REQUEST_QUEUE_AREA_SIZE + SERV_RESPONSE_QUEUE_AREA_SIZE)

/* Value for checking number of queue requests per VM ( VM_REQ_QUE_CNT_CHECK ) */
#define VM_REQ_QUE_CNT_CHECK_OK         (0U)
#define VM_REQ_QUE_CNT_CHECK_REACHED    (1U)

/* Value for RAM area check ( CHECK_VALUE ) */
#define VALUE_FOR_RAM_AREA_CHECK        (0xA5A5A5A5U)

/*====================================================================================*/
/* Data pattern of alignment check                                                    */
/*====================================================================================*/
#define ALIGNMENT_64BYTE_CHECK_PATTERN      (0x0000003fU)      /* 64 byte alignment  */
#define ALIGNMENT_4BYTE_CHECK_PATTERN       (0x00000003U)      /*  4 byte alignment  */
#define ALIGNMENT_2BYTE_CHECK_PATTERN       (0x00000001U)      /*  2 byte alignment  */

/**************************************************************************************/
/* Type definition                                                                    */
/**************************************************************************************/
/* None */

/**************************************************************************************/
/* Enumeration                                                                        */
/**************************************************************************************/
/* None */

/**************************************************************************************/
/* Structure Definition                                                               */
/**************************************************************************************/

typedef struct ICUM_COMM_PE_INFO
{
    volatile uint32_t*  p_icu2pes;
    volatile uint32_t*  p_pe2icufs;
    volatile uint32_t*  p_pe2icuie;
    volatile uint32_t*  p_icu2pef;
    volatile uint32_t*  p_icu2pefc;
    volatile uint32_t*  p_icu2peie;
    volatile uint32_t*  p_icu2peis;
    volatile uint32_t*  p_semape;
    volatile uint32_t*  p_semape_ns;
    uint32_t            inticup_pesel_to_pe;
    uint32_t            secure_mode_bit;
} ICUM_COMM_PE_INFO_t;

/*====================================================================================*/
/* Union for pointer manipulation                                                     */
/*====================================================================================*/
typedef union ptr_manip
{
    void                *p_ptr;
    uint32_t            *p_uint32_ptr;
    volatile uint32_t   *p_vlt_ptr;
    uintptr_t            val;
} ptr_manip_t;

/***************************************************************************************/
/* Prototypes                                                                          */
/***************************************************************************************/
static uint32_t d_COMM_PE_GetSemaphore(uint8_t target_pe, uint8_t request);
static uint32_t d_COMM_PE_FreeSemaphore(uint8_t target_pe, uint8_t response);
static void d_COMM_PE_VmRequestCountCheck(uint32_t *p_queptr, r_icumif_vm_id_t vm_id, uint32_t *p_chk_result);

#endif /* ICUM_D_COMM_PE_H */

