/* * Function : bsp_sc_init * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 bsp_sc_init(void) { u32 ret = 0; memset(&g_sc_stat,0,sizeof(sc_status_stru)); /* sem create */ osl_sem_init(0,&g_sc_stat.sc_api_sem); osl_sem_init(0,&g_sc_stat.sc_tsk_sem); /* task create */ #ifdef __OS_VXWORKS__ ret = (u32)osl_task_init("sc_ccore_task",128,4096,(OSL_TASK_FUNC)sc_icc_task,NULL,(void*)&g_sc_stat.sc_taskid); #elif defined(__OS_RTOSCK__) ret = (u32)osl_task_init("sc_ccore_task",57,4096,(OSL_TASK_FUNC)sc_icc_task,NULL,(void*)&g_sc_stat.sc_taskid); #endif if(ret) { sc_error_printf("init task failed!\n"); return BSP_ERR_SC_TASK_INIT_FAIL; } /* register icc event */ if(ICC_OK!=bsp_icc_event_register(SC_ICC_CHAN_ID, sc_icc_msg_proc,NULL,NULL,NULL)) { sc_error_printf("register icc channel failed!\n"); return BSP_ERR_SC_SEM_INIT_FAIL; } sc_printf("[SC]: init success.\n"); return SC_OK; }
/* * Function : sc_icc_task * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ void sc_icc_task(void) { s32 read_len = 0; s32 sc_fp = 0; s8* sc_path = (s8*)SC_PACKET_TRANS_FILE; sc_icc_stru icc_recv = {MISC_SC_OPT_BUTT}; /* coverity[no_escape] */ /* coverity[loop_top] */ for(;;) { osl_sem_down(&g_sc_stat.sc_tsk_sem); sc_debug_printf("get sem ok!\n"); read_len = bsp_icc_read(SC_ICC_CHAN_ID, (u8*)&icc_recv, sizeof(sc_icc_stru)); if(read_len > (s32)sizeof(sc_icc_stru)) { osl_sem_up(&g_sc_stat.sc_tsk_sem); sc_error_printf("bsp icc read error, chanid :0x%x ret :0x%x\n",SC_ICC_CHAN_ID,read_len); continue; } else if(0 >= read_len) { sc_error_printf("bsp icc read error, length is 0x%x!\n", read_len); continue ; } if( MISC_SC_OPT_READ == icc_recv.sc_opt_type) { if(SC_OK == icc_recv.sc_cnf_ret) { sc_fp = bsp_open(sc_path, (RFILE_RDONLY), 0660); /* [false alarm]: fortify 误报*/ if(sc_fp < 0) { sc_error_printf("open file %s failed!\n",sc_path); g_sc_stat.sc_opt_ret = BSP_ERR_SC_NO_FILE; osl_sem_up(&g_sc_stat.sc_api_sem); continue ; } read_len = bsp_read((u32)sc_fp, (s8 *)(g_sc_stat.sc_ram_addr), g_sc_stat.sc_ram_len); /* [false alarm]: fortify 误报*/ if(read_len != (s32)(g_sc_stat.sc_ram_len)) { sc_error_printf("read %s fail, read len is 0x%x, given len is 0x%x!\n",sc_path,read_len,g_sc_stat.sc_ram_len); bsp_close((u32)sc_fp); g_sc_stat.sc_opt_ret = BSP_ERR_SC_READ_FILE_FAIL; osl_sem_up(&g_sc_stat.sc_api_sem); continue ; } bsp_close((u32)sc_fp); } } sc_debug_printf("send to api interface\n"); g_sc_stat.sc_opt_ret = icc_recv.sc_cnf_ret; osl_sem_up(&g_sc_stat.sc_api_sem); } }
/* * Function : sc_bakup * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 sc_bakup(s8 *pdata, u32 len) { s32 sc_fp = 0; s32 wlen = 0; u32 sc_mtd_len = 0; struct mtd_info* mtd; sc_fp = bsp_open((char *)SC_PACKET_TRANS_FILE,(RFILE_RDONLY),0660); if(!sc_fp) { sc_error_printf("bsp_open error, chanid :0x%x sc_fp :0x%x\n",SC_ICC_CHAN_ID,sc_fp); return BSP_ERR_SC_NO_FILE; } else { sc_debug_printf("bsp_open ok, file is 0x%x!\n",sc_fp); } wlen = bsp_read(sc_fp, pdata, len); if(wlen != len) { sc_error_printf("bsp_read error, opt_len :0x%x sc_ram_len :0x%x\n", wlen, len); bsp_close(sc_fp); return BSP_ERR_SC_READ_FILE_FAIL; } else { sc_debug_printf("bsp_read ok, len is 0x%x!\n",(u32)(wlen)); } bsp_close(sc_fp); mtd = get_mtd_device_nm((char*)SC_BACKUP_SEC_NAME); if (IS_ERR(mtd)) { sc_error_printf("get mtd device err! %s\n",mtd); return BSP_ERR_READ_MTD_FAIL; } sc_mtd_len = mtd->size; sc_debug_printf("mtd len: 0x%x\n",sc_mtd_len); put_mtd_device(mtd); if((sc_mtd_len < SC_MTD_PTABLE_OFFSET) || (len >= SC_MTD_PTABLE_OFFSET)) { sc_error_printf("mtd length err! sc_mtd_len: 0x%x, len: 0x%x\n",sc_mtd_len, len); return BSP_ERR_READ_LGTH_FAIL; } wlen = bsp_nand_write((char*)SC_BACKUP_SEC_NAME, (sc_mtd_len - SC_MTD_PTABLE_OFFSET), pdata, len); if(wlen != BSP_OK) { sc_error_printf("mtd length err! wlen 0x%x, len is 0x%x\n",wlen,len); return BSP_ERR_SC_WRITE_FILE_FAIL; } sc_debug_printf("sc write to nand ok, len is 0x%x!\n",(u32)(wlen)); return SC_OK; }
void sc_test_read(u32 read_cnt) { u8* read_buf = NULL; u32 i; if(read_cnt>0) { read_buf = osl_malloc(read_cnt); if(NULL != read_buf) { memset(read_buf,0,read_cnt); /* write to file*/ (void)bsp_sc_restore(read_buf, read_cnt); for(i=0;i<read_cnt;i++) { if(0x5A != read_buf[i]) { sc_error_printf("data is wrong, i is %d,data is 0x%x!\n",i,read_buf[i]); } } osl_free(read_buf); } } }
/* * Function : sc_icc_msg_proc * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 sc_icc_msg_proc(u32 chanid, u32 len, void* pdata) { if(chanid != SC_ICC_CHAN_ID) { sc_error_printf(" sc icc channel error :0x%x\n",chanid); return BSP_ERR_SC_ICC_READ; } osl_sem_up(&g_sc_stat.sc_tsk_sem); sc_debug_printf("recv from ccore ok!\n"); return SC_OK; }
/* * Function : bsp_sc_kernel_init * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 bsp_sc_kernel_init(void) { s32 ret = SC_ERROR; osl_sem_init(0,&g_sc_stat.sc_tsk_sem); ret = osl_task_init("sc_acore_task",15,1024,sc_icc_task,NULL,(void*)&g_sc_stat.sc_taskid); if(ret) { sc_error_printf("init task failed!\n"); return BSP_ERR_SC_TASK_INIT_FAIL; } if(ICC_OK != bsp_icc_event_register(SC_ICC_CHAN_ID, sc_icc_msg_proc,NULL,NULL,NULL)) { sc_error_printf("register icc channel failed!\n"); return BSP_ERR_SC_SEM_INIT_FAIL ; } sc_printf("[SC]: init success.\n"); return SC_OK; }
/* * Function : sc_icc_task * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ void sc_icc_task(void) { s32 ret = -1; s32 icc_len = 0; sc_icc_stru icc_trans; /* coverity[no_escape] */ for(;;) { osl_sem_down(&g_sc_stat.sc_tsk_sem); sc_debug_printf("icc task, recv from acore ok, chanid :0x%x\n",SC_ICC_CHAN_ID); icc_len = bsp_icc_read(SC_ICC_CHAN_ID, (u8 * )&icc_trans, sizeof(sc_icc_stru)); if((icc_len > sizeof(sc_icc_stru))) { sc_error_printf("bsp icc read error, chanid :0x%x opt_len :0x%x\n",SC_ICC_CHAN_ID,icc_len); osl_sem_up(&g_sc_stat.sc_tsk_sem); continue; } else if(0 >= icc_len) { sc_debug_printf("bsp icc read error, length is 0!\n"); continue ; } g_sc_stat.sc_ram_len = icc_trans.sc_total_len; sc_debug_printf("len is 0x%x\n", g_sc_stat.sc_ram_len); icc_trans.sc_cnf_ret = SC_OK; /* get buffer */ g_sc_stat.sc_ram_addr = (u8* )osl_malloc(icc_trans.sc_total_len); if(!g_sc_stat.sc_ram_addr) { sc_error_printf("bsp icc read error, chanid :0x%x ret :0x%x\n",SC_ICC_CHAN_ID,ret); icc_trans.sc_cnf_ret = BSP_ERR_SC_MALLOC_FAIL; goto confirm; } else { sc_debug_printf("malloc ok!\n"); } if(MISC_SC_OPT_WRITE== icc_trans.sc_opt_type) { if(SC_OK != sc_bakup(g_sc_stat.sc_ram_addr, g_sc_stat.sc_ram_len)) { icc_trans.sc_cnf_ret = BSP_ERR_SC_WRITE_FILE_FAIL; } } else { if(SC_OK != sc_restore(g_sc_stat.sc_ram_addr, g_sc_stat.sc_ram_len)) { icc_trans.sc_cnf_ret = BSP_ERR_SC_READ_FILE_FAIL; } } osl_free(g_sc_stat.sc_ram_addr); confirm: /* send pkt to modem */ icc_len = bsp_icc_send(ICC_CPU_MODEM, SC_ICC_CHAN_ID, (u8*)&icc_trans, sizeof(sc_icc_stru)); if(icc_len != sizeof(sc_icc_stru)) { sc_error_printf("send to modem failed 0,icc_len is 0x%x!\n",icc_len); } else { sc_debug_printf("send to mdoem ok,icc_len is 0x%x!\n",icc_len); } continue; } }
/* * Function : sc_restore * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 sc_restore(s8 *pdata, u32 len) { s32 sc_fp = 0; s32 rlen = 0; s32 wlen = 0; u32 sc_mtd_len = 0; struct mtd_info* mtd; mtd = get_mtd_device_nm((char*)SC_BACKUP_SEC_NAME); if (IS_ERR(mtd)) { sc_error_printf("get mtd device err! %s\n",mtd); return BSP_ERR_READ_MTD_FAIL; } sc_mtd_len = mtd->size; put_mtd_device(mtd); if((sc_mtd_len < SC_MTD_PTABLE_OFFSET) || (len >= SC_MTD_PTABLE_OFFSET)) { sc_error_printf("mtd length err! size 0x%x\n",mtd->size); return BSP_ERR_READ_LGTH_FAIL; } rlen = bsp_nand_read((char*)SC_BACKUP_SEC_NAME, (sc_mtd_len - SC_MTD_PTABLE_OFFSET), pdata, len, NULL); if(rlen != BSP_OK) { sc_error_printf("mtd length err! read_ret 0x%x, len is 0x%x\n",rlen,len); return BSP_ERR_SC_READ_FILE_FAIL; } else { sc_debug_printf("mtd length read ok len is 0x%x\n",rlen); } /* write to file */ sc_fp = bsp_open((char*)SC_PACKET_TRANS_FILE,(RFILE_CREAT|RFILE_RDWR),0660); if(!sc_fp) { sc_error_printf("bsp_open error, chanid :0x%x sc_fp :0x%x\n",SC_ICC_CHAN_ID,sc_fp); return BSP_ERR_SC_NO_FILE; } else { sc_debug_printf("bsp_open ok, file is 0x%x!\n",sc_fp); } /* write to file */ wlen = bsp_write(sc_fp, pdata, len); if(wlen != len) { sc_error_printf("bsp_write error, chanid :0x%x wlen :0x%x, len : 0x%x\n",SC_ICC_CHAN_ID,wlen,len); bsp_close(sc_fp); return BSP_ERR_SC_WRITE_FILE_FAIL; } else { sc_debug_printf("bsp_write ok,wlen is 0x%x",wlen); } bsp_close(sc_fp); return SC_OK; }
/* * Function : sc_opt_comm * Discription: c core nv init,this phase build upon the a core kernel init, * this phase after icc init,this phase ensure to use all nv api normal * start at this phase ,ops global ddr need spinlock * Parameter : none * Output : result * History : */ s32 sc_opt_comm(MISC_SC_OPT_ENUM sc_enum, u8* pRamAddr, u32 len) { s32 write_len = 0; s32 sc_fp = 0; s8* sc_path = (s8*)SC_PACKET_TRANS_FILE; sc_icc_stru sc_send_msg = {MISC_SC_OPT_BUTT}; /* judge para */ if(sc_enum >= MISC_SC_OPT_BUTT) { sc_error_printf("para wrong, sc_enum is %d!\n",sc_enum); /* [false alarm]: fortify 误报*/ return BSP_ERR_SC_INVALID_PARAM; } if((NULL == pRamAddr)||( len >= SC_MTD_PTABLE_OFFSET)) { sc_error_printf("para wrong, addr is 0x%x, len is 0x%x!\n",(unsigned long)pRamAddr,len); return BSP_ERR_SC_INVALID_PARAM; } g_sc_stat.sc_ram_addr = pRamAddr; g_sc_stat.sc_ram_len = len; g_sc_stat.sc_opt_type = sc_enum; if(bsp_access(sc_path,0)) { bsp_remove(sc_path); } if(MISC_SC_OPT_WRITE == sc_enum) { sc_fp = bsp_open(sc_path, (RFILE_CREAT|RFILE_RDWR), 0660); /* [false alarm]: fortify 误报*/ if(sc_fp < 0) { sc_error_printf("open file %s failed!\n",sc_path); return BSP_ERR_SC_NO_FILE; } write_len = bsp_write((u32)sc_fp, (const s8*)pRamAddr, len); /* [false alarm]: fortify 误报*/ if(write_len != (s32)len) { sc_error_printf("write %s fail, write len is 0x%x, given len is 0x%x!\n",sc_path,write_len,len); bsp_close((u32)sc_fp); return BSP_ERR_SC_WRITE_FILE_FAIL; } bsp_close((u32)sc_fp); } /* send handshake packet */ sc_send_msg.sc_opt_type = sc_enum; sc_send_msg.sc_total_len = len; write_len = bsp_icc_send(ICC_CPU_APP, SC_ICC_CHAN_ID, (u8*)&sc_send_msg, sizeof(sc_icc_stru)); if((u32)write_len != sizeof(sc_icc_stru)) { sc_error_printf("send to app filed, write_len is 0x%x!\n",write_len); return BSP_ERR_SC_ICC_SEND; } else { sc_debug_printf("send to app ok!\n"); } /* wait recv sem */ if(osl_sem_downtimeout(&g_sc_stat.sc_api_sem, 1000)) { sc_error_printf("get result from acore timeout failed!\n"); return BSP_ERR_SC_SEM_TIMEOUT; } else { if((g_sc_stat.sc_opt_type != sc_enum)||(SC_OK != g_sc_stat.sc_opt_ret) ) { sc_error_printf("recv wrong result,sc_icc_type is %d, sc_ret is %d!\n",g_sc_stat.sc_opt_type,g_sc_stat.sc_opt_ret); return BSP_ERR_SC_CNF_ABNORMAL; } } if(bsp_access(sc_path, 0)) { bsp_remove(sc_path); } sc_debug_printf("api opterate %d success !\n",g_sc_stat.sc_opt_type); return SC_OK; }