/******************************************************************
 * @file  msg_interface.s.c
 * @brief:    [file description] 
 * @author: guicheng.liu
 * @Date 2022年7月2日
 * COPYRIGHT NOTICE: (c) smartlogictech. All rights reserved. 
 * Change_date         Owner         Change_content
 * 2022年7月2日        guicheng.liu       create file

*****************************************************************/

/**************************include******************************/
#include <type_define.h>
#include "log_interface.h"
#include "msg_transfer_layer.h"
#include "error_record.h"
#include "task_define.h"
#include "msg_interface.h"
#include "drv_ape.h"
#include "osp_ape.h"

// #include "palladium_debug.h"
/**************************function******************************/

extern uint32_t g_dma_tag_l2g;

/*!   
* @brief:  物理层和L2L3, OAM, FH的接口,此接口将平台消息相关的接口封装在一个接口内:
            msg_transfer_start
            msg_transfer_alloc_msg
            DMA
            msg_transfer_send_msg
            msg_transfer_end

* @author:  guicheng.liu
* @Date:  2022年7月2日
* @param: queue_num :        [队列号]
* @param: msg_ptr :          [消息指针,要求是DM空间]
* @param: msg_len :          [消息长度]
*/
uint32_t osp_phy_msg_send( char* msg_ptr, uint32_t msg_len)
{
    uint32_t offset = 0;
    char* buf = NULLPTR;
    uint32_t avail_size = 0;
    uint32_t ret = 0;
    uint32_t core_id = get_core_id();
    uint32_t dm_to_dam_addr = 0;
    const uint32_t buf_size = 512;
    uint16_t cu_flag = U_PLANE;
    HandleId_t handler;
    handler.port_id = get_ucp_port_id();
    handler.inst_id = 0;
    handler.type_id = CU_SPLIT;

    MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND);

    ret = msg_transfer_send_start(handler.value);
    // if (0 != ret)
    // {
    //     ERROR_RECORD(ERROR_CONFIG+3, ret, queue_num, core_id, port_id);
    //     MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
    //     return 1;
    // }
    #ifndef IDE_TEST
    ret = msg_transfer_alloc_msg(handler.value, cu_flag, buf_size,
                                &buf, &avail_size, &offset);
    #endif
    // if (0 != ret)
    // {
    //     ERROR_RECORD(ERROR_CONFIG+4, ret, queue_num, core_id, port_id);
    //     MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
    //     return 2;
    // }

    if ((ECS_RFM0_CORE_ID == core_id) || 
        (PT_RFM0_CORE_ID == core_id) || 
        (0 == (core_id%2)))
    {
        dm_to_dam_addr = 0x100000;
    }     

    ape_csu_dma_1D_L2G_ch0ch1_transfer((uint64_t)(msg_ptr - dm_to_dam_addr),
                                        (uint64_t)buf, 
                                        msg_len, 
                                        g_dma_tag_l2g, 1);

    ret = msg_transfer_send_msg(handler.value, cu_flag,
                                (uint8_t*)buf, offset, msg_len);
    // if (0 != ret)
    // {
    //     ERROR_RECORD(ERROR_CONFIG+5, ret, queue_num, core_id, port_id);
    //     MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
    //     return 3;
    // }

    #ifndef IDE_TEST
    ret = msg_transfer_send_end(handler.value);
    #endif

    // if (0 != ret)
    // {
    //     ERROR_RECORD(ERROR_CONFIG+6, ret, queue_num, core_id, port_id);
    //     MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
    //     return 4;
    // }
    // MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_OK);

    return ret;
}

/*!   
* @brief:  
* @author:  guicheng.liu
* @Date:  2022年7月20日
* @param: queue_num :        [队列号]
* @param: msg_ptr :          [多消息指针数组,要求是都是DM空间]
* @param: msg_len :          [消息长度数组]
* @param: msg_num :          [消息个数]
*/
uint32_t osp_phy_multi_msgs_send(uint32_t queue_num, 
                                char** msg_ptr, 
                                uint32_t* msg_len,
                                uint32_t msg_num)
{
    uint32_t offset = 0;
    char* buf = NULLPTR;
    char* buf_tmp = NULLPTR;
    uint32_t avail_size = 0;
    uint32_t ret = 0;
    uint32_t port_id = get_ucp_port_id();
    uint32_t core_id = get_core_id();
    uint32_t dm_to_dam_addr = 0;
    uint32_t msg_total_len = 0;
    const uint16_t buf_size = 512;
	MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND);

    ret = msg_transfer_send_start(port_id);

    if (0 != ret)
    {
        ERROR_RECORD(ERROR_CONFIG+7, ret, queue_num, core_id, port_id);
        MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
        return 1;
    }
    #ifndef IDE_TEST
    ret = msg_transfer_alloc_msg(port_id, C_PLANE, buf_size,
                                &buf, &avail_size, &offset);
    #endif
    if (0 != ret)
    {
        ERROR_RECORD(ERROR_CONFIG+8, ret, queue_num, core_id, port_id);
        MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
        return 2;
    }

    if ((ECS_RFM0_CORE_ID == core_id) || 
        (PT_RFM0_CORE_ID == core_id) || 
        (0 == (core_id%2)))
    {
        dm_to_dam_addr = 0x100000;
    }     

    buf_tmp = buf;

    //待驱动平台的链式DMA接口提供后,替换为链式DMA搬移
    for (uint32_t i = 0; i < msg_num; i++)
    {
        ape_csu_dma_1D_L2G_ch0ch1_transfer((uint64_t)(msg_ptr[i] - dm_to_dam_addr), 
                                                    (uint64_t)buf_tmp, 
                                                    msg_len[i], 
                                                    g_dma_tag_l2g, 1);
        buf_tmp = buf_tmp + msg_len[i];
        msg_total_len = msg_total_len + msg_len[i];
    }

    ret = msg_transfer_send_msg(port_id, C_PLANE, 
                                (uint8_t*)buf, offset, msg_len);
    if (0 != ret)
    {
        ERROR_RECORD(ERROR_CONFIG+9, ret, queue_num, core_id, port_id);
        MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
        return 3;
    }
    #ifndef IDE_TEST
    ret = msg_transfer_send_end(port_id);
    #endif
    if (0 != ret)
    {
        ERROR_RECORD(ERROR_CONFIG+10, ret, queue_num, core_id, port_id);
        MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_ERR);
        return 4;
    }
	MSG_TRANSFER_RECORD(core_id, TASK_MSG_SEND_OK);

    return ret;
}



/*!   
* @brief:  消息释放接口
* @author:  guicheng.liu
* @Date:  2022年7月8日
* @param: queue_num :        [队列ID]
* @param: el_ind :           [buffer id]
* @param: buf :              [消息地址]
*/
uint32_t osp_phy_msg_free(uint32_t queue_num, 
                                uint32_t el_ind, 
                                char* buf)
{
    uint32_t ret = 0;
    uint32_t port_id = get_ucp_port_id();

    // ret = msg_transfer_free_msg(port_id, 
    //                             queue_num, 
    //                             el_ind, 
    //                             buf);

    if (0 != ret)
    {
        ERROR_RECORD(ERROR_CONFIG+2, ret, queue_num, 0, port_id);
        return ret;
    }

    return ret;
}

 /*!   
 * @brief:  
 * @author:  guicheng.liu
 * @Date:  2023年2月10日
 * @param: msg_addr :         [消息体的地址]
 * @param: msg_len :          [消息体的长度（单位：字节）]
 * @param: msg_type :         [消息类型]
 * @param: src_core_id :      [源核ID]
 * @param: dst_core_id :      [目的核ID]
 * @param: src_task_id :      [源任务ID]
 * @param: dst_task_id :      [目的任务ID]
 函数返回值：
     0： 成功返回
    -2： 入参错误
    -1： 错误返回
 */
int32_t phy_et_msg_send(uint32_t msg_addr,
                            uint32_t msg_len,
                            uint8_t  msg_type,
                            uint8_t  src_core_id,
                            uint8_t  dst_core_id,
                            uint8_t  src_task_id,
                            uint8_t  dst_task_id)
{
    int32_t ret = 0;
    //TASK_MSG_RECORD(src_core_id, src_task_id, TASK_MSG_SEND);
    char     *paddr   = NULL;
    paddr = osp_alloc_msg(msg_len);
    if (NULL == paddr)
    {

        LOG_ERROR_S("phy_et_msg ERR\n");
        return 1;
    }


    memcpy_ext(paddr, msg_addr, msg_len);

    ret = osp_send_msg(paddr,
                        msg_len,
                        msg_type,
                        src_core_id,
                        dst_core_id,
                        src_task_id,
                        dst_task_id);
    if (0 == ret)
    {
        //(src_core_id, src_task_id, TASK_MSG_SEND_OK);
    }
    else
    {
        //TASK_MSG_RECORD(src_core_id, src_task_id, TASK_MSG_SEND_ERR);
    }

    return ret;
}

