#ifndef __OSP_MSG_H__
#define __OSP_MSG_H__

#define OSP_MSG_DBG_ENABLE

#ifdef OSP_MSG_DBG_ENABLE
typedef struct OSP_MSG_DBG_INFO
{
    uint32_t u32msg_inner_send_ok;
    uint32_t u32msg_inner_send_ng;
    uint32_t u32msg_swque_recv;
    uint32_t u32msg_swque_in_ok;
    uint32_t u32msg_swque_in_ng;
    uint32_t u32msg_post_sem_cnt;
    uint32_t u32msg_inter_send_ok;
    uint32_t u32msg_inter_send_ng;
    uint32_t u32msg_hwque_recv;
}osp_msg_dbg_info_t;

void osp_show_msg_dbg_info_by_taskid(uint8_t taskid);

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
void osp_show_msg_dbg_info_by_coreid_taskid(uint8_t coreid, uint8_t taskid);
#endif /* UCP_OSP_DBG_HW_CNT_ENABLE */

#endif /* OSP_MSG_DBG_ENABLE */

/* 消息类型 */
typedef enum OSP_MSG_TYPE
{
    UCP4008_KERNEL_INTER = 0,   /* 核间通信 */
    UCP4008_OSP_HANDSHAKE = 7,  /* 握手消息 */
    UCP4008_OSP_CFG_FILE,       /* 微码配置文件消息 */
    UCP4008_OSP_DDR_INIT,       /* DDR初始化配置消息 */
    UCP4008_OSP_DUMP,           /* DUMP消息 */
    UCP4008_OSP_LOG,            /* LOG消息 */
    UCP4008_OSP_SHELL,          /* Shell消息 */
    UCP4008_OSP_SHELL_ECHO,     /* Shell回显消息 */
    UCP4008_KERNEL_INNER = 0xFF,/* 核内通信 */
}osp_msg_type;

/* 消息头 */
typedef struct OSP_MSG_HEAD
{
    uint32_t msg_size;      /* 消息长度（单位：字节） */
    uint8_t  msg_type;      /* 消息类型 */
    uint8_t  msg_type_oam;
    uint8_t  msg_padding[2];/* 保留字段 */

    uint8_t  src_core_id;   /* 源核ID */
    uint8_t  dst_core_id;   /* 目的核ID */
    uint8_t  src_task_id;   /* 源任务ID */
    uint8_t  dst_task_id;   /* 目的任务ID */

    uint8_t  data[0];
}osp_msg_head;

#define OSP_MSG_HEAD_LEN sizeof(osp_msg_head)

typedef struct OSP_MSG_TICK_INFO
{
    /* send 相关 */
    uint32_t u32_send_tick;      // osp_send_msg
    uint32_t u32_inque1_tick;    // osp_send_msg(inter)
    uint32_t u32_inque2_tick;    // osp_send_msg(inter)
    uint32_t u32_sw_enque1_tick; // osp_send_msg(inner)
    uint32_t u32_sw_enque2_tick; // osp_send_msg(inner)
    uint32_t u32_sem_post_tick;  // osp_send_msg(inner)

    /* recv 相关 */
    uint32_t u32_recv_tick;
    uint32_t u32_recv_msg_tick;  // osp_recv_msg
    uint32_t u32_deque1_tick;    // osp_recv_msg
    uint32_t u32_deque2_tick;    // osp_recv_msg
    uint32_t u32_sem_wait_tick;  // osp_event_task
    uint32_t u32_callback_tick;  // osp_event_task

    /* 硬件队列中断相关 */
    uint32_t u32_irq_tick;        // osp_hw_que_irq
    uint32_t u32_irq_deque1_tick; // osp_hw_que_irq
    uint32_t u32_irq_deque2_tick; // osp_hw_que_irq
    uint32_t u32_irq_enque1_tick; // osp_hw_que_irq
    uint32_t u32_irq_enque2_tick; // osp_hw_que_irq
    uint32_t u32_irq_post_tick;   // osp_hw_que_irq
}osp_msg_tick_info;

/* 函数接口定义       */
extern char *osp_alloc_msg(int size);   /* 申请消息通信的内存空间(DDR) */

extern int osp_send_msg(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);
extern void osp_recv_msg(osp_msg_head **pmsg_head);      /* 接收侧接收了消息之后通过task_id 做基本的分发 */

extern int osp_hw_que_init(uint8_t ape_id, uint8_t que_id);

extern void osp_get_hw_que_cnt(uint32_t *pu32irq_cnt, uint32_t *pu32irq_ok, uint32_t *pu32irq_err, uint32_t *pu32sw_err);

extern void osp_show_msg_info(void);

#endif /* __OSP_MSG_H__ */

