//#include "ucps2.h"
#include "osp_type_def.h"
#include "osp_msg.h"
#include "osp_sw_queue.h"
#include "osp_task.h"
#include "osp_sem.h"
#include "osp_mem.h"
#include "osp_msg_que.h"
#include "err_num.h"

#include "hwque.h"
#include "smartos.h"
#include "ucp_printf.h"
#include "ucp_tick.h"
#include "spu_shell.h"

#ifdef UCP_TICK_ENABLE
osp_msg_tick_info st_tick_info;
#endif

#ifdef OSP_MSG_DBG_ENABLE
osp_msg_dbg_info_t gst_osp_msg_dbg_info[TASK_ID_MAX];
#endif

int g_hq_vector = -1;
extern int g_que_id;
extern int g_ape_id;

/***************************************************************************/
/* 消息通信包括：核内通信和核间通信                                              */
/* 根据讨论现在消息都放到了DDR上，不管是核间的，还是核内的                           */

/* 在发送消息时，平台来判断是核内通信还是核间通信，核间通信时，平台申请硬件队列空间 */
/* 对消息的发送和接收，由osp来区分，核内通过软件队列来实现，核间通过硬件队列来实现 */
/***************************************************************************/
/* 申请消息通信的内存空间(DDR) */
char *osp_alloc_msg(int size)
{
#ifdef UCP_TICK_ENABLE
    uint32_t clockBegin,clockEnd;
    int32_t  clockCnt;
    rdmcycle(&clockBegin);
#endif

    uint32_t addr = 0;
    int      ret  = 0;

    if ((size+OSP_MSG_HEAD_LEN) > OSP_APE_MSG_SIG_SIZE)
    {
        UCP_PRINT_ERROR("osp_alloc_msg: error (size = 0x%08x)\r\n", size);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 70), size);
#endif
        return NULL;
    }

    ret = osp_msg_que_deque(&addr);
    if (OSP_OK != ret)
    {
        /* 没有取到地址空间 */
        UCP_PRINT_ERROR("osp_alloc_msg: error (no addr)\r\n");
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 71), 0xffff);
#endif
        return NULL;
    }
    //debug_write(OSP_DEBUG_POT(g_ape_id, 72), ((uint32_t)addr + (uint32_t)OSP_MSG_HEAD_LEN));
#ifdef UCP_TICK_ENABLE
    rdmcycle(&clockEnd);
    clockCnt = clockEnd - clockBegin;
    debug_write(OSP_DEBUG_POT(g_ape_id, 202), clockCnt);
#endif
    return (char*)((uint32_t)addr + (uint32_t)OSP_MSG_HEAD_LEN);
}

#ifdef UCP_OSP_DBG_ENABLE
static uint32_t g_u32_inner_cnt = 0;
static uint32_t g_u32_inter_cnt = 0;
static uint32_t g_u32_inner_cnt_ok  = 0;
static uint32_t g_u32_inter_cnt_ok  = 0;
static uint32_t g_u32_inner_cnt_err = 0;
static uint32_t g_u32_inter_cnt_err = 0;
#endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
static uint32_t gu32_osp_sendto_que0_ok = 0;    // #0
static uint32_t gu32_osp_sendto_que1_ok = 0;
static uint32_t gu32_osp_sendto_que2_ok = 0;
static uint32_t gu32_osp_sendto_que3_ok = 0;
static uint32_t gu32_osp_sendto_que4_ok = 0;
static uint32_t gu32_osp_sendto_que5_ok = 0;
static uint32_t gu32_osp_sendto_que6_ok = 0;
static uint32_t gu32_osp_sendto_que7_ok = 0;
static uint32_t gu32_osp_sendto_que8_ok = 0;
static uint32_t gu32_osp_sendto_que9_ok = 0;
static uint32_t gu32_osp_sendto_que10_ok = 0;
static uint32_t gu32_osp_sendto_que11_ok = 0;
static uint32_t gu32_osp_sendto_que0_ng = 0;    // #12
static uint32_t gu32_osp_sendto_que1_ng = 0;
static uint32_t gu32_osp_sendto_que2_ng = 0;
static uint32_t gu32_osp_sendto_que3_ng = 0;
static uint32_t gu32_osp_sendto_que4_ng = 0;
static uint32_t gu32_osp_sendto_que5_ng = 0;
static uint32_t gu32_osp_sendto_que6_ng = 0;
static uint32_t gu32_osp_sendto_que7_ng = 0;
static uint32_t gu32_osp_sendto_que8_ng = 0;
static uint32_t gu32_osp_sendto_que9_ng = 0;
static uint32_t gu32_osp_sendto_que10_ng = 0;
static uint32_t gu32_osp_sendto_que11_ng = 0;

static uint32_t gu32_osp_recv_que0 = 0;     // #24
static uint32_t gu32_osp_recv_que1 = 0;
static uint32_t gu32_osp_recv_que2 = 0;
static uint32_t gu32_osp_recv_que3 = 0;
static uint32_t gu32_osp_recv_que4 = 0;
static uint32_t gu32_osp_recv_que5 = 0;
static uint32_t gu32_osp_recv_que6 = 0;
static uint32_t gu32_osp_recv_que7 = 0;
static uint32_t gu32_osp_recv_que8 = 0;
static uint32_t gu32_osp_recv_que9 = 0;
static uint32_t gu32_osp_recv_que10 = 0;
static uint32_t gu32_osp_recv_que11 = 0;

static uint32_t gu32_osp_sendto_inner_ok = 0;   // #36
static uint32_t gu32_osp_sendto_inner_ng = 0;   // #37
#endif

/*
函数名称：osp_send_msg
函数功能：发送消息用于核间或者核内通信
函数参数：msg_addr：消息体的地址
          msg_len：消息体的长度（单位：字节）
          msg_type：消息类型
          src_core_id：源核ID
          dst_core_id：目的核ID
          src_task_id：源任务ID
          dst_task_id：目的任务ID
函数返回值：
    0： 成功返回
   -2： 入参错误
   -1： 错误返回
*/
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)
{
#ifdef UCP_TICK_ENABLE
        uint32_t clockBegin,clockEnd;
        int32_t  clockCnt;
        rdmcycle(&clockBegin);
        rdmcycle(&st_tick_info.u32_send_tick);
#endif

    osp_msg_head *pmsg_head = NULL;
    osp_tcb      *p_osp_tcb = NULL;
    osp_msg_head st_msg_head;
    int  ret_queue = -1;

    pmsg_head = (osp_msg_head*)((uint32_t)msg_addr - (uint32_t)OSP_MSG_HEAD_LEN);

    st_msg_head.msg_size = msg_len;
    st_msg_head.msg_type = msg_type;
    st_msg_head.msg_type_oam = 0x00;
    st_msg_head.src_core_id = src_core_id;
    st_msg_head.dst_core_id = dst_core_id;
    st_msg_head.src_task_id = src_task_id;
    st_msg_head.dst_task_id = dst_task_id;

    memcpy_ucp((void*)pmsg_head, (void*)&st_msg_head, OSP_MSG_HEAD_LEN);
    __ucps2_synch(0);

    /* 核内通信，消息入软件队列 */
    //if (UCP4008_KERNEL_INNER == msg_type)
    if (src_core_id == dst_core_id)
    {
        //g_u32_inner_cnt++;
        /* 核内通信：入软件队列 */
        p_osp_tcb = (osp_tcb*)TCB_GET(dst_task_id);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_sw_enque1_tick);
#endif
        ret_queue = osp_sw_enque(pmsg_head, p_osp_tcb->que_head);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_sw_enque2_tick);
#endif
        if (0 == ret_queue)
        {
            //g_u32_inner_cnt_ok++;
            /* 入队成功，释放信号量，触发事件任务 */
            osp_post_event_sem(dst_task_id);
#ifdef OSP_MSG_DBG_ENABLE
            gst_osp_msg_dbg_info[src_task_id].u32msg_inner_send_ok++;
            gst_osp_msg_dbg_info[dst_task_id].u32msg_swque_in_ok++;
#endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
            debug_write(OSP_DEBUG_HW_POT(g_ape_id, 36), ++gu32_osp_sendto_inner_ok);
#endif

#ifdef UCP_TICK_ENABLE
            rdmcycle(&st_tick_info.u32_sem_post_tick);
#endif
        }
        else
        {
            //g_u32_inner_cnt_err++;
            #ifdef OSP_MSG_DBG_ENABLE
            gst_osp_msg_dbg_info[src_task_id].u32msg_inner_send_ng++;
            gst_osp_msg_dbg_info[dst_task_id].u32msg_swque_in_ng++;
            #endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
            debug_write(OSP_DEBUG_HW_POT(g_ape_id, 37), ++gu32_osp_sendto_inner_ng);
#endif
        }
#ifdef UCP_OSP_DBG_ENABLE
        debug_write(OSP_DEBUG_POT(g_ape_id, 73), g_u32_inner_cnt_err);
        debug_write(OSP_DEBUG_POT(g_ape_id, 74), g_u32_inner_cnt);
        debug_write(OSP_DEBUG_POT(g_ape_id, 75), g_u32_inner_cnt_ok);
#endif
    }
    else
    {
        //g_u32_inter_cnt++;
        /* 核间通信：入硬件队列 */
        UCP_PRINT_LOG("osp_send_msg: dst_que_id = 0x%08x, addr = 0x%08x\r\n", dst_core_id, msg_addr);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_inque1_tick);
#endif
        ret_queue = smart_in_que(dst_core_id, msg_addr);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_inque2_tick);
#endif
        if (0 != ret_queue)
        {
            UCP_PRINT_ERROR("osp_send_msg: error(smart_in_que) que_id = 0x%08x addr = 0x%08x\r\n", dst_core_id, msg_addr);
            //g_u32_inter_cnt_err++;
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 18), ret_queue);
            #ifdef OSP_MSG_DBG_ENABLE
            gst_osp_msg_dbg_info[src_task_id].u32msg_inter_send_ng++;
            #endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
            switch (dst_core_id)
            {
                case 0:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 12), ++gu32_osp_sendto_que0_ng);
                    break;
                }
                case 1:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 13), ++gu32_osp_sendto_que1_ng);
                    break;
                }
                case 2:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 14), ++gu32_osp_sendto_que2_ng);
                    break;
                }
                case 3:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 15), ++gu32_osp_sendto_que3_ng);
                    break;
                }
                case 4:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 16), ++gu32_osp_sendto_que4_ng);
                    break;
                }
                case 5:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 17), ++gu32_osp_sendto_que5_ng);
                    break;
                }
                case 6:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 18), ++gu32_osp_sendto_que6_ng);
                    break;
                }
                case 7:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 19), ++gu32_osp_sendto_que7_ng);
                    break;
                }
                case 8:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 20), ++gu32_osp_sendto_que8_ng);
                    break;
                }
                case 9:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 21), ++gu32_osp_sendto_que9_ng);
                    break;
                }
                case 10:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 22), ++gu32_osp_sendto_que10_ng);
                    break;
                }
                case 11:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 23), ++gu32_osp_sendto_que11_ng);
                    break;
                }
                default:
                {
                    break;
                }
            }
#endif
        }
        else
        {
            //g_u32_inter_cnt_ok++;
            #ifdef OSP_MSG_DBG_ENABLE
            gst_osp_msg_dbg_info[src_task_id].u32msg_inter_send_ok++;
            #endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
            switch (dst_core_id)
            {
                case 0:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 0), ++gu32_osp_sendto_que0_ok);
                    break;
                }
                case 1:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 1), ++gu32_osp_sendto_que1_ok);
                    break;
                }
                case 2:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 2), ++gu32_osp_sendto_que2_ok);
                    break;
                }
                case 3:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 3), ++gu32_osp_sendto_que3_ok);
                    break;
                }
                case 4:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 4), ++gu32_osp_sendto_que4_ok);
                    break;
                }
                case 5:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 5), ++gu32_osp_sendto_que5_ok);
                    break;
                }
                case 6:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 6), ++gu32_osp_sendto_que6_ok);
                    break;
                }
                case 7:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 7), ++gu32_osp_sendto_que7_ok);
                    break;
                }
                case 8:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 8), ++gu32_osp_sendto_que8_ok);
                    break;
                }
                case 9:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 9), ++gu32_osp_sendto_que9_ok);
                    break;
                }
                case 10:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 10), ++gu32_osp_sendto_que10_ok);
                    break;
                }
                case 11:
                {
                    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 11), ++gu32_osp_sendto_que11_ok);
                    break;
                }
                default:
                {
                    break;
                }
            }
#endif
        }
#ifdef UCP_OSP_DBG_ENABLE
        debug_write(OSP_DEBUG_POT(g_ape_id, 76), g_u32_inter_cnt_err);
        debug_write(OSP_DEBUG_POT(g_ape_id, 77), g_u32_inter_cnt);
        debug_write(OSP_DEBUG_POT(g_ape_id, 78), g_u32_inter_cnt_ok);
#endif
    }
#ifdef UCP_TICK_ENABLE
    rdmcycle(&clockEnd);
    clockCnt = clockEnd - clockBegin;
    debug_write(OSP_DEBUG_POT(g_ape_id, 203), clockCnt);
#endif

    return ret_queue;
}

/* 消息通信：接收消息 */
/* 只能接收到核内消息，从软队列中收到消息，由接收到消息来触发某任务 */
void osp_recv_msg(osp_msg_head **pmsg_head)
{
#ifdef UCP_TICK_ENABLE
    rdmcycle(&st_tick_info.u32_recv_msg_tick);
#endif

    int task_id;
    osp_tcb *l_tcb = NULL;
    //debug_write(OSP_DEBUG_POT(g_ape_id, 65), 0x10012002);

    task_id = osp_get_cur_task_id();

    l_tcb = (osp_tcb*)TCB_GET(task_id);
#ifdef UCP_TICK_ENABLE
    rdmcycle(&st_tick_info.u32_deque1_tick);
#endif
    osp_sw_deque(pmsg_head, l_tcb->que_head);
#ifdef UCP_TICK_ENABLE
    rdmcycle(&st_tick_info.u32_deque2_tick);
#endif
#ifdef OSP_MSG_DBG_ENABLE
    gst_osp_msg_dbg_info[task_id].u32msg_swque_recv++;
#endif

    return ;
}

uint32_t g_irq_num = 0;
uint32_t g_irq_out_err = 0;
uint32_t g_irq_sw_err = 0;
uint32_t g_irq_ok = 0;
uint32_t g_irq_task_id_err = 0;

/* 硬件队列回调函数 */
void osp_hw_que_irq(void)
{
    int ret = -1;
    uint32_t idx = 0;
    osp_tcb *l_tcb = NULL;
    osp_msg_head *pmsg_head = NULL;
    uint8_t  dst_task_id = 0;
#ifdef UCP_TICK_ENABLE
    rdmcycle(&st_tick_info.u32_irq_tick);
#endif

    g_irq_num++;
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 58), g_irq_num);
#endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
    debug_write(OSP_DEBUG_HW_POT(g_ape_id, 38), g_irq_num);
#endif

    ret = smart_que_is_empty(g_que_id);
    //while(ret!= 0)
    while(ret == 0)
    {
        /* 消息出队 */
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_irq_deque1_tick);
#endif
        ret = smart_out_que(g_que_id, &idx);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_irq_deque2_tick);
#endif

      if (0 != ret)
        {
            g_irq_out_err++;
            UCP_PRINT_ERROR("[osp_hw_que_irq]: smart_out_que error... que_id = 0x%x \r\n", g_que_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 59), g_irq_out_err);
#endif
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 27), ret);

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
            debug_write(OSP_DEBUG_HW_POT(g_ape_id, 40), g_irq_out_err);
#endif

            return ;
        }
        UCP_PRINT_LOG("[osp_hw_que_irq]: smart_out_que(0x%x), addr = 0x%08x\r\n", g_que_id, idx);

        /* 出队后走软件队列通知 */
        pmsg_head = (osp_msg_head*)((uint32_t)idx - (uint32_t)OSP_MSG_HEAD_LEN);

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
        uint8_t src_core_id = do_read_byte((char*)(&pmsg_head->src_core_id));
        //__ucps2_synch(0);

        switch (src_core_id)
        {
            case 0:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 24), ++gu32_osp_recv_que0);
                break;
            }
            case 1:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 25), ++gu32_osp_recv_que1);
                break;
            }
            case 2:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 26), ++gu32_osp_recv_que2);
                break;
            }
            case 3:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 27), ++gu32_osp_recv_que3);
                break;
            }
            case 4:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 28), ++gu32_osp_recv_que4);
                break;
            }
            case 5:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 29), ++gu32_osp_recv_que5);
                break;
            }
            case 6:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 30), ++gu32_osp_recv_que6);
                break;
            }
            case 7:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 31), ++gu32_osp_recv_que7);
                break;
            }
            case 8:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 32), ++gu32_osp_recv_que8);
                break;
            }
            case 9:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 33), ++gu32_osp_recv_que9);
                break;
            }
            case 10:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 34), ++gu32_osp_recv_que10);
                break;
            }
            case 11:
            {
                debug_write(OSP_DEBUG_HW_POT(g_ape_id, 35), ++gu32_osp_recv_que11);
                break;
            }
            default:
            {
                break;
            }
        }
#endif

        dst_task_id = do_read_byte((char*)(&pmsg_head->dst_task_id));
        //__ucps2_synch(0);

        if (OSP_OK != osp_task_id_is_true(dst_task_id))
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 66), dst_task_id);
            debug_write(OSP_DEBUG_POT(g_ape_id, 67), ++g_irq_task_id_err);
#endif
            return ;
        }
#ifdef OSP_MSG_DBG_ENABLE
        gst_osp_msg_dbg_info[dst_task_id].u32msg_hwque_recv++;
#endif
        l_tcb = (osp_tcb*)TCB_GET(dst_task_id);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_irq_enque1_tick);
#endif
        ret = osp_sw_enque(pmsg_head, l_tcb->que_head);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_irq_enque2_tick);
#endif

        if (OSP_OK != ret)
        {
            g_irq_sw_err++;
            UCP_PRINT_ERROR("[osp_hw_que_irq]: osp_sw_enque error (dst_task_id = 0x%08x)\r\n", dst_task_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 60), dst_task_id);
            debug_write(OSP_DEBUG_POT(g_ape_id, 61), g_irq_sw_err);
#endif
#ifdef OSP_MSG_DBG_ENABLE
            gst_osp_msg_dbg_info[dst_task_id].u32msg_swque_in_ng++;
#endif
            return ;
        }

#ifdef OSP_MSG_DBG_ENABLE
        gst_osp_msg_dbg_info[dst_task_id].u32msg_swque_in_ok++;
#endif

        /* osp_sw_enque ok --> send sem */
        osp_post_event_sem(dst_task_id);

#ifdef OSP_MSG_DBG_ENABLE
        gst_osp_msg_dbg_info[dst_task_id].u32msg_post_sem_cnt++;
#endif

#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_irq_post_tick);
#endif

        g_irq_ok++;
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 62), g_irq_ok);
#endif

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
        debug_write(OSP_DEBUG_HW_POT(g_ape_id, 39), g_irq_ok);
#endif

        /* 继续取下一个 */
        ret = smart_que_is_empty(g_que_id);
    }

    return ;
}

int osp_hw_que_init(uint8_t ape_id, uint8_t que_id)
{
    int ret = -1;
    int que_dep   = -1;
    int que_width = -1;
    int que_used  = -1;
    int que_cpuid = -1;
    int apeId = get_core_id();
    uint8_t u8_loop = 0;

    /* communication init */
    do
    {
        ret = smart_hq_init(ape_id);
    }
    while(ret != 0);
    UCP_PRINT_LOG("[osp_hw_que_init]: smart_hq_init OK\r\n");
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 50), ape_id);
    debug_write(OSP_DEBUG_POT(g_ape_id, 51), que_id);
#endif

    /* Band */
    ret = smart_que_bind(ape_id, que_id);
    if (0 != ret)
    {
        UCP_PRINT_ERROR("[osp_hw_que_init]: smart_que_bind(ape_id = %x, que_id = %x) retunr error\r\n", ape_id, que_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff01);
#endif
        debug_write(DBG_DDR_ERR_IDX(apeId, 22), ret);
        return -OSP_HW_BAND;
    }

    /* Get queue info*/
    ret = smart_get_que_info(g_que_id, &que_dep, &que_width, &que_used, &que_cpuid);
    if (0 != ret)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff02);
#endif
        debug_write(DBG_DDR_ERR_IDX(apeId, 20), ret);
    }
    UCP_PRINT_LOG("[osp_hw_que_init]: que_id(0x%08x),dep(0x%08x),width(0x%08x),used(0x%08x),cpuid(0x%08x) \r\n", g_que_id, que_dep,que_width,que_used,que_cpuid);

    /* Get queue vector */
    g_hq_vector = smart_get_hq_vector(ape_id, que_id);
    if (0 >= g_hq_vector)
    {
        UCP_PRINT_ERROR("[osp_hw_que_init]: smart_get_hq_vector error!!!!!(ape_id = 0x%08x)....\r\n", ape_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff03);
#endif
        debug_write(DBG_DDR_ERR_IDX(apeId, 16), g_hq_vector);
        return -OSP_HW_VECT;
    }
    UCP_PRINT_LOG("[osp_hw_que_init]: hq_vector = 0x%x (apeid = 0x%x, queid = 0x%x)\r\n", g_hq_vector, ape_id, que_id);
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 55), g_hq_vector);
#endif

    /* Set req */
    ret = smart_irq_request(g_hq_vector, osp_hw_que_irq);
    if (0 != ret)
    {
        UCP_PRINT_ERROR("[osp_hw_que_init]: smart_irq_request error!!!!!(ape_id = 0x%08x)....\r\n", ape_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff04);
#endif
        debug_write(DBG_DDR_ERR_IDX(apeId, 5), ret);
        return -OSP_HW_IRQ;
    }

    /* enable no-empty irq */
    for (u8_loop = 0; u8_loop < 8; u8_loop++)
    {
        ret = smart_enable_q_nempty(que_id);
        if (OSP_OK == ret)
        {
            break;
        }
    }
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 53), u8_loop);
#endif
    if (OSP_OK != ret)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff05);
        debug_write(OSP_DEBUG_POT(g_ape_id, 54), ret);
#endif
       return -OSP_HW_EMPTY_ERR;
    }

    ret = osp_msg_que_init(que_id);
    if (OSP_OK != ret)
    {
        UCP_PRINT_ERROR("[osp_hw_que_init]: osp_msg_que_init error!!!!!(ape_id = 0x%08x)....\r\n", ape_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 52), 0xff06);
#endif
        return -OSP_PAR_ILL;
    }
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 56), 0x0101);
#endif

    UCP_PRINT_LOG("[osp_hw_que_init]: OK \r\n");

#ifdef UCP_TICK_ENABLE
    memset(&st_tick_info, 0, sizeof(st_tick_info));
#endif

#ifdef OSP_MSG_DBG_ENABLE
    memset(&gst_osp_msg_dbg_info, 0, sizeof(osp_msg_dbg_info_t)*TASK_MAX);
#endif

    return OSP_OK;
}

void osp_get_hw_que_cnt(uint32_t *pu32irq_cnt, uint32_t *pu32irq_ok, uint32_t *pu32irq_err, uint32_t *pu32sw_err)
{
    *pu32irq_cnt = g_irq_num;
    *pu32irq_ok  = g_irq_ok;
    *pu32irq_err = g_irq_out_err;
    *pu32sw_err  = g_irq_sw_err;

    return ;
}

#ifdef OSP_MSG_DBG_ENABLE
void osp_show_msg_info(void)
{
    uint8_t ucCoreId = 0;
    uint8_t i = 0;
    osp_tcb *tcb_val = NULL;
    char pbuf[2048];
    int len           = 0;

    ucCoreId = get_core_id();

    len = sprintf(pbuf,"\n\r%-8s%-8s%-25s%-10s%-5s\n\r","coreId", "Id",  "name","inner","inter");

    for (i = 0; i < g_taskid_num; i++, len=0)
    {
        tcb_val = (osp_tcb*)g_tcb_handler_tbl[g_task_id_table[i]];

        len += sprintf(pbuf +len,"%-8u%-8u%-25s%-10u%-5u\n\r",ucCoreId,tcb_val->task_id, tcb_val->task_name, 
                       gst_osp_msg_dbg_info[g_task_id_table[i]].u32msg_inner_send_ok,
                       gst_osp_msg_dbg_info[g_task_id_table[i]].u32msg_inter_send_ok); 
        
        spu_shellinfo_to_arm(pbuf, len, UCP4008_OSP_SHELL);
    }

    return;
}

void osp_show_msg_dbg_info_by_taskid(uint8_t taskid)
{
    int len           = 0;
    char pbuf[2048];

    if (OSP_OK != osp_task_id_is_true(taskid))
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 68), taskid);
#endif
        return ;
    }

    len = sprintf(pbuf,"\n\r%-8s%-4s%-10s%-10s%-10s%-10s%-10s%-10s%-10s%-10s%-10s\n\r",
                   "coreId", "Id","inner_ok", "inner_ng", 
                   "sw_in_ok", "sw_in_ng", "post_sem",
                   "inter_ok", "inter_ng", "sw_recv", "hw_recv");

    len += sprintf(pbuf +len,"%-8u%-4u%-10u%-10u%-10u%-10u%-10u%-10u%-10u%-10u%-10u\n\r",
                   g_ape_id, taskid, 
                   gst_osp_msg_dbg_info[taskid].u32msg_inner_send_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_inner_send_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_in_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_in_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_post_sem_cnt,
                   gst_osp_msg_dbg_info[taskid].u32msg_inter_send_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_inter_send_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_recv,
                   gst_osp_msg_dbg_info[taskid].u32msg_hwque_recv);

    spu_shellinfo_to_arm(pbuf, len, UCP4008_OSP_SHELL);

    return ;
}

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
void osp_show_msg_dbg_info_by_coreid_taskid(uint8_t coreid, uint8_t taskid)
{
    int len           = 0;
    char pbuf[2048];

    if (g_ape_id != coreid)
    {
        return ;
    }

    if (OSP_OK != osp_task_id_is_true(taskid))
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 68), taskid);
#endif
        return ;
    }

    len = sprintf(pbuf,"\n\r%-8s%-4s%-10s%-10s%-10s%-10s%-10s%-10s%-10s%-10s%-10s\n\r",
                   "coreId", "Id","inner_ok", "inner_ng", 
                   "sw_in_ok", "sw_in_ng", "post_sem",
                   "inter_ok", "inter_ng", "sw_recv", "hw_recv");

    len += sprintf(pbuf +len,"%-8u%-4u%-10u%-10u%-10u%-10u%-10u%-10u%-10u%-10u%-10u\n\r",
                   g_ape_id, taskid, 
                   gst_osp_msg_dbg_info[taskid].u32msg_inner_send_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_inner_send_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_in_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_in_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_post_sem_cnt,
                   gst_osp_msg_dbg_info[taskid].u32msg_inter_send_ok,
                   gst_osp_msg_dbg_info[taskid].u32msg_inter_send_ng,
                   gst_osp_msg_dbg_info[taskid].u32msg_swque_recv,
                   gst_osp_msg_dbg_info[taskid].u32msg_hwque_recv);

    spu_shellinfo_to_arm(pbuf, len, UCP4008_OSP_SHELL);

    return ;
}

#endif /* UCP_OSP_DBG_HW_CNT_ENABLE */
#endif

