/***************************************************************************** 函 数 名 : hifireset_loadhifibin 功能描述 : 加载hifi映像 输入参数 : 无 输出参数 : 无 返 回 值 : int *****************************************************************************/ int hifireset_loadhifibin(void) { /* load hifi */ if (TRUE == check_secure_mode()) { printk(KERN_INFO"RESET LOADHIFI: It's secure mode\n"); if (execute_load_hifi((int)HIFI_SAFE_LOAD, (unsigned long)HIFI_SHARE_ADDR_BASE)) { return BSP_RESET_ERROR; } } else { printk(KERN_INFO"RESET LOADHIFI: It's un-secure mode\n"); if (execute_load_hifi((int)HIFI_UNSAFE_LOAD, (unsigned long)HIFI_SHARE_ADDR_BASE)) { return BSP_RESET_ERROR; } } return BSP_RESET_OK; }
int __init loadmodem_init(void) { #ifndef CONFIG_ARM64 #define MODEM_IMAGE_ADDR (0x3E00) unsigned int buff_phy = MODEM_IMAGE_ADDR; DSP_IMAGE_HEAD_STRU *header = NULL; MODEM_IMAGE_BUFFER_FLAG_STRU *buffer_flag = NULL; char *modem_loadaddr = NULL; int ret, i; char *tmp_addr = NULL; char *modem_baseaddr = NULL; char *gudsp_load_addr = NULL; char *gudsp_flag_addr = NULL; char *gudsp_head_addr = NULL; char *gudsp_bin_addr = NULL; char *modem_sec_imageaddr = NULL; unsigned int head_len = 0; unsigned int bin_len = 0; if (!is_async_loadmodem()) return 0; /* Dont protect modem memory */ /*platform_ddr_protect_init(0);*/ modem_baseaddr = (char *)ioremap_nocache(MODEM_SYS_MEM_ADDR, MODEM_SYS_MEM_SIZE); gudsp_load_addr = (char *)ioremap_nocache(ECS_GUDSP_LOAD_ADDR, ECS_GUDSP_LOAD_SIZE); gudsp_flag_addr = gudsp_load_addr; gudsp_head_addr = gudsp_flag_addr + GUDSP_IMAGE_FLAG_SIZE; gudsp_bin_addr = gudsp_head_addr + GUDSP_IMAGE_HEAD_SIZE; modem_sec_imageaddr = modem_baseaddr + MODEM_IMAGE_ADDR - VRL_SIZE; buffer_flag = (MODEM_IMAGE_BUFFER_FLAG_STRU*)gudsp_flag_addr; buffer_flag->ulProtectWord1 = 0x5A5A5A5A; buffer_flag->ulSecNum = 0; buffer_flag->ulHeadAddr = (unsigned int)GUDSP_IMAGE_HEAD_ADDR; buffer_flag->ulProtectWord2 = 0xA5A5A5A5; modem_loadaddr = modem_baseaddr + MODEM_IMAGE_ADDR; header = (DSP_IMAGE_HEAD_STRU *)modem_loadaddr; /*printk(KERN_ERR "%s:modem_loadaddr: %p modem_baseaddr:%p \n",__FUNCTION__, modem_loadaddr, modem_baseaddr);*/ /* secure check */ if (check_secure_mode()){ ret = check_image_in_ram((unsigned int *)modem_sec_imageaddr); if (ret == 0){ printk(KERN_INFO "%s:secure check ok \n",__FUNCTION__); }else{ printk(KERN_ERR "%s:secure check error \n",__FUNCTION__); goto error; } } for(i = 0; i < header->uwSecNum; i++) { /* If attribute is BUFFER, move to buffer */ if (header->astSections[i].enLoadAttrib == DSP_IMAGE_SEC_LOAD_BUFFER ) { if((GUDSP_IMAGE_HEAD_SIZE < head_len + sizeof(DSP_IMAGE_SEC_STRU)) || (GUDSP_IMAGE_BUFFER_SIZE < bin_len + header->astSections[i].uwSize) || (GUDSP_IMAGE_SECTION_MAX <= buffer_flag->ulSecNum)) { printk(KERN_ERR "load to buffer failed, section's size beyond buffer's size.\n"); return -1; } memcpy((void*)(gudsp_bin_addr + bin_len), (void*)(modem_loadaddr + header->astSections[i].uwSrcOffset), header->astSections[i].uwSize); header->astSections[i].uwSrcOffset = (unsigned int)GUDSP_IMAGE_BIN_ADDR + bin_len; memcpy((void*)(gudsp_head_addr + head_len), (void*)(&header->astSections[i]), sizeof(DSP_IMAGE_SEC_STRU)); head_len += sizeof(DSP_IMAGE_SEC_STRU); bin_len += header->astSections[i].uwSize; buffer_flag->ulSecNum++; //printk(KERN_ERR "%s:section buffer: %p\n",__FUNCTION__,tmp_addr); } /* If attribute is STATIC/MODEM_ENTRY, move to addr to run */ else if ((header->astSections[i].enLoadAttrib == DSP_IMAGE_SEC_LOAD_MODEM_ENTRY ) || (header->astSections[i].enLoadAttrib == DSP_IMAGE_SEC_LOAD_STATIC )) { tmp_addr = modem_baseaddr + header->astSections[i].uwDesOffset; printk(KERN_INFO"%s:section: %p \n",__FUNCTION__, tmp_addr); if (header->astSections[i].uwDesOffset != buff_phy + header->astSections[i].uwSrcOffset){ memmove(tmp_addr, (modem_loadaddr + header->astSections[i].uwSrcOffset), header->astSections[i].uwSize); //printk(KERN_ERR "%s:copy %p to %p size 0x%x \n",__FUNCTION__, (buff_phy + header->astSections[i].uwSrcOffset), header->astSections[i].uwDesOffset,header->astSections[i].uwSize); //printk(KERN_ERR "%s:copy %p to %p size 0x%x \n",__FUNCTION__, (modem_loadaddr + header->astSections[i].uwSrcOffset), tmp_addr, header->astSections[i].uwSize); } } /* else do nothing */ else { /* do nothing */ } } printk(KERN_INFO"Load modem done.\n"); /* unreset modem */ start_modem(); #else TEEC_Result result = SEC_ERROR; /*64bit secure check */ /*Do the SecureOs locally for modem if the result is ok then start the modem else start the kernel but hold the modem */ result = TEEK_start_modem(); if (result == TEEC_SUCCESS) { printk(KERN_INFO "%s:secure check ok \n",__FUNCTION__); } else { printk(KERN_ERR "%s:secure check error \n",__FUNCTION__); goto error; } #endif error: #ifndef CONFIG_ARM64 iounmap(modem_baseaddr); iounmap(gudsp_load_addr); #endif return 0; }