/*lint -save -e774 -e944 -e506*/
MAILBOX_GLOBAL int mailbox_init(void)
{

    if (MAILBOX_INIT_MAGIC == g_mailbox_handle.init_flag) {
        /*考虑到单核下电重启,静态数据不会丢失,这里只打印告警,
          返回错误的话,后面的平台初始化将调不到,IPC中断无法注册*/
        return mailbox_logerro_p1(MAILBOX_ERR_GUT_ALREADY_INIT, g_mailbox_handle.init_flag);
    }

    /*TODO:进行单核下电重启特性开发时,这行需要删除*/
    (void)mailbox_memset(&g_mailbox_handle, 0x00, sizeof(struct mb));

#ifdef MAILBOX_OPEN_MNTN
    if ((MAILBOX_HEAD_BOTTOM_ADDR > (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_HEAD_LEN)) ||
       (MAILBOX_MEMORY_BOTTOM_ADDR > (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_LENGTH)))
    {
        bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_MBX,
            "mailbox address overflow: headbuttom valid(0x%x), config(0x%x)!\n\
          \r                          databuttom valid(0x%x), config(0x%x)!"RT,
        (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_HEAD_LEN), MAILBOX_HEAD_BOTTOM_ADDR,
        (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_LENGTH), MAILBOX_MEMORY_BOTTOM_ADDR);
        return mailbox_logerro_p0(MAILBOX_CRIT_GUT_MEMORY_CONFIG);
    }
#endif

    /*初始化邮箱主体部分,创建邮箱总句柄。*/
    if (MAILBOX_OK != mailbox_create_box(&g_mailbox_handle,
                          &g_mailbox_global_cfg_tbl[0], MAILBOX_LOCAL_CPUID)) {
        return mailbox_logerro_p0(MAILBOX_ERR_GUT_CREATE_BOX);
    }

    /*初始化平台差异部分*/
    if (MAILBOX_OK != mailbox_init_platform()) {
        return mailbox_logerro_p0(MAILBOX_ERR_GUT_INIT_PLATFORM);
    }

    g_mailbox_handle.init_flag = MAILBOX_INIT_MAGIC;

#ifndef _DRV_LLT_
//    mailbox_ifc_test_init();
#endif

    bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_MBX, "mb init OK!"RT);

    return MAILBOX_OK;
}
/*****************************************************************************
 函 数 名  : mailbox_init_mem
 接口类型  : 对内接口
 功能描述  : 初始化邮箱通道内存,初始化邮箱头及邮箱体,设置结构初始值和保护字等
 输入参数  : struct mb_cfg *config -- 某个邮箱内存通道描述符
 输出参数  : 无
 返 回 值  : 成功或失败
 调用函数  :
 被调函数  :

 修改历史      :
  1.日    期   : 2012年9月24日
    作    者   : 莫南 00176101
    修改内容   : 新生成函数

*****************************************************************************/
MAILBOX_LOCAL long mailbox_init_mem(struct mb_cfg *config)
{
    struct mb_head       *head = (struct mb_head*)config->head_addr;
    unsigned long         data_addr       = config->data_addr;
    unsigned long         data_size       = config->data_size;

    /* Modified by c64416 for hifi mailbox, 2013/09/24, begin */
    /*这里也属于入参判断*/
    if ((0 == data_addr) || (MAILBOX_NULL == head) || (0 == data_size)) {
        mailbox_logerro_p1(MAILBOX_ERR_GUT_INIT_CORESHARE_MEM, config->butt_id);
        return MAILBOX_OK;
    }
    /* Modified by c64416 for hifi mailbox, 2013/09/24, end */

    /*初始化邮箱体*/
    mailbox_memset((signed char *)data_addr, 0, data_size);

    /*初始化邮箱头部保护字*/
    mailbox_write_reg(data_addr, MAILBOX_PROTECT1);
    mailbox_write_reg(data_addr + MAILBOX_PROTECT_LEN, MAILBOX_PROTECT2);

    /*初始化邮箱尾部保护字*/
    mailbox_write_reg((data_addr + data_size) - (2*MAILBOX_PROTECT_LEN),
                MAILBOX_PROTECT1);
    mailbox_write_reg((data_addr + data_size) - MAILBOX_PROTECT_LEN,
                MAILBOX_PROTECT2);

     /*初始化邮箱头*/
    head->ulFront         = 0;
    head->ulFrontslice    = 0;
    head->ulRear          = head->ulFront;
    head->ulRearslice     = 0;
    head->ulProtectWord4  = MAILBOX_PROTECT2;
    head->ulProtectWord3  = MAILBOX_PROTECT1;
    head->ulProtectWord2  = MAILBOX_PROTECT2;
    head->ulProtectWord1  = MAILBOX_PROTECT1;

    return MAILBOX_OK;
}
MAILBOX_GLOBAL long mailbox_init(void)
{
	unsigned long offset = 0;
	int i = 0;
	struct mb_head *head = NULL;

	if (MAILBOX_INIT_MAGIC == g_mailbox_handle.init_flag) {
		/*考虑到单核下电重启,静态数据不会丢失,这里只打印告警,
		返回错误的话,后面的平台初始化将调不到,IPC中断无法注册*/
		return mailbox_logerro_p1(MAILBOX_ERR_GUT_ALREADY_INIT, g_mailbox_handle.init_flag);
	}

	printk("func = %s, line = %d baseaddr = 0x%x\n", __func__, __LINE__, MAILBOX_MEM_BASEADDR);

	g_shareMemBase = ioremap(MAILBOX_MEM_BASEADDR, MAILBOX_MEM_LENGTH);
	/*初始化邮箱中的数据*/
//memset(g_shareMemBase,0x0,MAILBOX_MEM_LENGTH);

	if(NULL == g_shareMemBase) {
		printk("func = %s, mmap mailbox mem error!!\n", __func__);
		return mailbox_logerro_p0(MAILBOX_CRIT_GUT_MEMORY_CONFIG);
	}

	offset = (unsigned long)g_shareMemBase - MAILBOX_MEM_BASEADDR;
	for(i = 0; i < MAILBOX_GLOBAL_CHANNEL_NUM; i++) {
		g_mailbox_global_cfg_tbl[i].head_addr = g_mailbox_global_cfg_tbl[i].head_addr + offset;
		g_mailbox_global_cfg_tbl[i].data_addr = g_mailbox_global_cfg_tbl[i].data_addr + offset;

		printk("i = %d, head_addr = 0x%lx, data_addr = 0x%lx\n", i,
			   g_mailbox_global_cfg_tbl[i].head_addr, g_mailbox_global_cfg_tbl[i].data_addr);

		/*初始化邮箱头*/
		head = (struct mb_head *)g_mailbox_global_cfg_tbl[i].head_addr;
		head->ulFront = 0x0;
		head->ulRear = 0x0;
		head->ulFrontslice = 0x0;
		head->ulRearslice = 0x0;
	}

	/*TODO:进行单核下电重启特性开发时,这行需要删除*/
	mailbox_memset(&g_mailbox_handle, 0x00, sizeof(struct mb));

#ifdef MAILBOX_OPEN_MNTN
	if ((MAILBOX_HEAD_BOTTOM_ADDR > (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_HEAD_LEN)) ||
		(MAILBOX_MEMORY_BOTTOM_ADDR > (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_LENGTH))) {
		mailbox_out(("mailbox address overflow: headbuttom valid(0x%x), config(0x%x)!\n\\r							databuttom valid(0x%x), config(0x%x)!\n",
					 (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_HEAD_LEN), MAILBOX_HEAD_BOTTOM_ADDR,
					 (MAILBOX_MEM_BASEADDR + MAILBOX_MEM_LENGTH), MAILBOX_MEMORY_BOTTOM_ADDR));
		return mailbox_logerro_p0(MAILBOX_CRIT_GUT_MEMORY_CONFIG);
	}
#endif

	/*初始化邮箱主体部分,创建邮箱总句柄。*/
	if (MAILBOX_OK != mailbox_create_box(&g_mailbox_handle,
										 &g_mailbox_global_cfg_tbl[0], MAILBOX_LOCAL_CPUID)) {
		return mailbox_logerro_p0(MAILBOX_ERR_GUT_CREATE_BOX);
	}

	/*初始化平台差异部分*/
	if (MAILBOX_OK != mailbox_init_platform()) {
		return mailbox_logerro_p0(MAILBOX_ERR_GUT_INIT_PLATFORM);
	}

	g_mailbox_handle.init_flag = MAILBOX_INIT_MAGIC;

#ifndef _DRV_LLT_
//mailbox_ifc_test_init();
#endif

//fixme: there isn't go to unremap
	g_slice_reg = (void*)ioremap(SLICE_REG, 0x4);
	if (NULL == g_slice_reg) {
		printk("ioremap of slice reg fail.\n");
	}

	mailbox_out(("mb init OK!\n"));

	return MAILBOX_OK;
}