/***************************************************************************** 函 数 名 : mailbox_init 接口类型 : 对外接口 功能描述 : 邮箱模块平台适配部分初始化 输入参数 : 输出参数 : 无 返 回 值 : 线程操作句柄 调用函数 : mailbox_init_platform 被调函数 : 修改历史 : 1.日 期 : 2012年9月24日 作 者 : 莫南 00176101 修改内容 : 新生成函数 详细描述: 初始化邮箱并初始化与平台相关的差异化部分,在邮箱初始化的时候调用。 *****************************************************************************/ signed 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:进行单核下电重启特性开发时,这行需要删除*/ 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)!"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 mailbox_out(("mb init OK!"RT)); return MAILBOX_OK; }
MAILBOX_EXTERN struct mb *mailbox_get_mb(void) { if (MAILBOX_INIT_MAGIC == g_mailbox_handle.init_flag) { return &g_mailbox_handle; } /*错误邮箱未初始化*/ mailbox_out(("error: mb not init\n")); return MAILBOX_NULL; }
MAILBOX_EXTERN void mailbox_assert(unsigned long ErroNo) { #ifndef _DRV_LLT_ /*产品方案*/ if(0 == check_himntn(HIMNTN_MBFULL_ASSERT)) { systemError(BSP_MODU_MAILBOX, ErroNo, 0, 0, 0); } else { while (1) { mailbox_out(("mb Assert!\n")); msleep(1000); } } #endif }
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; }
MAILBOX_LOCAL long mailbox_request_channel( struct mb *mb, struct mb_buff ** mb_buf, unsigned long mailcode) { struct mb_head *head = MAILBOX_NULL; struct mb_queue *queue = MAILBOX_NULL; struct mb_buff *mbuff = MAILBOX_NULL; long ret_val = MAILBOX_OK; mailbox_dpm_device_get(); *mb_buf = MAILBOX_NULL; mbuff = mailbox_get_channel_handle(mb, mailcode); if (MAILBOX_NULL == mbuff) { ret_val = MAILBOX_ERRO; goto request_erro; } /*通过判断通道保护字,检查通道有没有初始化*/ head = (struct mb_head*)mbuff->config->head_addr; if (( (MAILBOX_PROTECT1 != head->ulProtectWord1) ) || (MAILBOX_PROTECT2 != head->ulProtectWord2) ||(MAILBOX_PROTECT1 != head->ulProtectWord3) || (MAILBOX_PROTECT2 != head->ulProtectWord4)) { #if 1/*k3 modify 保护字不正确重新初始化一下邮箱头,不要return影响通信流程,后续再找根因*/ /*保护字不正确,说明邮箱未初始化,或者内存被踩,报错。*/ /* do not check cause hifi maybe not pwr on when the first ipc message send */ mailbox_init_mem(mbuff->config); mailbox_logerro_p1(MAILBOX_NOT_READY, mailcode); #endif } if(mailbox_get_src_id(mailcode) == mb->local_id) { /* 不允许在中断中发邮件*/ if (MAILBOX_TRUE == mailbox_int_context()) { //TODO:接下来的开发(IFC for 低功耗)可能需要支持在中断中发送邮件,这里就需要锁中断。 ret_val = mailbox_logerro_p1(MAILBOX_ERR_GUT_SEND_MAIL_IN_INT_CONTEXT, mailcode); goto request_erro; } else { if (MAILBOX_OK != mailbox_mutex_lock(&mbuff->mutex)) { /*非中断发送,需要资源保护,获取当前通道资源。*/ ret_val = mailbox_logerro_p1(MAILBOX_CRIT_GUT_MUTEX_LOCK_FAILED, mailcode); goto request_erro; } } } mbuff->mailcode = mailcode; /*共享内存队列,需要依据邮箱头信息对队列操作符进行填充*/ queue = &mbuff->mail_queue; queue->front = queue->base + head->ulFront * sizeof(unsigned long); queue->rear = queue->base + head->ulRear * sizeof(unsigned long); mbuff->mb = mb; *mb_buf = mbuff; return MAILBOX_OK; request_erro: mailbox_out(("###mailbox_request_channel ERR! \n")); mailbox_dpm_device_put(); return ret_val; }