#ifndef __OSPMSGH__
#define __OSPMSGH__

#ifdef __cplusplus
extern "C" {
#endif


#define OSP_MEGQ_DEP            8192

#define OSP_MESSAGE_LEN sizeof(uint64_t)
extern char *gOspMsgQue;
#define IS_TIMER_MSG(pMsg)((pMsg->MsgType) == OSP_TIMER_TYPE)
#define OSP_MSG_QUE_SIZE (sizeof(Osp_MsgQ_Tcb))

typedef enum en_osp_msg_type
{
    OSP_TIMER_TYPE = 0x5555,
    OSP_SHELL_TYPE,

    /*OSP_STR_LOG          = 0x12350002,
    OSP_BIN_LOG      = 0x1234000a,*/
    OSP_STR_LOG      = 0x60,
    OSP_BIN_LOG      = 0x61,
    OSP_PLATFORM_LOG = 0x62,
    OSP_MAX_TYPE,
    
}EN_OSP_MSG_TYPE;

typedef struct tag_Osp_Msg_Head
{
    uint32_t   MsgType;                                                        
    uint32_t   MsgSize;   /*is just msgdata len, not include Osp_Msg_Head*/                                                      
    uint32_t   SrcId;                                                     
    uint32_t   DstId;
        
}Osp_Msg_Head;


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;

#if 0
typedef struct tag_Osp_Ape_Msg_Head
{
    U32   MsgType;                                                        
    U8    MsgSize;                                                        
    U8    Msg_Padding[3]; /*reserved*/

    U8    Src_Core_Id;                                                     
    U8    Dst_Core_Id;
    U8    Src_Task_Id;                                                     
    U8    Dst_Task_Id;

    U8    data[0];
}Osp_Ape_Msg_Head;
#endif
typedef struct tag_Osp_Timer_Msg_Block
{
    Osp_Msg_Head osp_msg_head;
    uint64_t data;
}Osp_Timer_Msg_Block;


#define APE_MSG_DADA_LEN(x)     (x->msg_size - APE_MSG_HEAD_SIZE)
#define APE_MSG_HEAD_SIZE       sizeof(Osp_Ape_Msg_Head)
#define APE_MSG_HEAD_TO_COMM(x)     (char *)((uint64_t)x + APE_MSG_HEAD_SIZE)
#define MSG_HEAD_SIZE           sizeof(Osp_Msg_Head)
#define MSG_HEAD_TO_COMM(x)     (char *)((uint64_t)x + MSG_HEAD_SIZE)
#define MSG_DADA_LEN(x)         (x->MsgSize)
#define MSG_TO_OFFSET(x)    ((uint64_t)x - (uint64_t)gOspMsgQue) 
#define OFFSET_TO_MSG(x)    (Osp_Msg_Head *)((uint64_t)x + (uint64_t)gOspMsgQue) 


typedef struct tag_Osp_MsgQ_Tcb
{
    Osp_SoftQue soft_que;
    uint64_t data[OSP_MEGQ_DEP];
}Osp_MsgQ_Tcb;


#define OSP_MSGQ_ENCNT(que) que->soft_que.EnCnt
#define OSP_MSGQ_DECNT(que) que->soft_que.DeCnt
#define OSP_MSGQ_CUR(que) que->soft_que.CurNum
#define OSP_MSGQ_DEP(que) que->soft_que.Dep
#define OSP_MSGQ_QUE(que) que->soft_que



extern int osp_create_msgq(Osp_MsgQ_Tcb *, char *name);
extern Osp_Msg_Head *osp_alloc_msg(uint32_t Len);
Osp_Msg_Head *osp_alloc_msgTimer(void);
Osp_Msg_Head *osp_alloc_msgCmd(uint32_t Len);
extern OSP_STATUS osp_send_msg(Osp_Msg_Head *p_MsgHead);
extern Osp_Msg_Head *osp_rev_msg(void);
extern Osp_Msg_Head *osp_rev_msgtry(void);
Osp_Msg_Head *osp_rev_msg_timeout(uint32_t timeout);

extern void osp_free_msg(Osp_Msg_Head *pHead);
extern OSP_STATUS osp_msg_que_init(void);

extern int dequetry(uint64_t *pvalue, Osp_MsgQ_Tcb *que);
extern int dequetimeout(uint64_t *pvalue, Osp_MsgQ_Tcb *que, uint32_t timeout);
extern Osp_Msg_Head *osp_rev_msgid(int id);
extern Osp_Msg_Head *osp_alloc_msgId(uint32_t Len, int id);
extern OSP_STATUS osp_send_msgId(Osp_Msg_Head *p_MsgHead,int id);
extern int osp_free_msgid(Osp_Msg_Head *pHead,int id);
extern OSP_STATUS osp_send_por_msg(Osp_Msg_Head *p_MsgHead, Osp_MsgQ_Tcb *que);
extern Osp_Msg_Head *osp_rev_promsg(Osp_MsgQ_Tcb *que);





#ifdef __cplusplus
}
#endif

#endif  /*__OSPMSGH__ */

