void efuse_handle_work(struct work_struct *work) { u32 i = 0; int length = 0; u32 channel_id = ICC_CHN_IFC << 16 | IFC_RECV_FUNC_EFUSE; EFUSE_DATA_STRU *msg = &efuse_msg; if(EFUSE_READ == (u32)msg->opt) { if(1 == efuse_debug_flag) { pr_info("efuse read start group %d length %d.\n", msg->start, msg->len); } msg->ret = bsp_efuse_read(msg->buf, msg->start,msg->len); if(1 == efuse_debug_flag) { pr_info("efuse read end group %d length %d.\n", msg->start, msg->len); for(i = 0;i < msg->len;i++) { pr_info("efuse buf[%d] is 0x%x.\n", i, msg->buf[i]); } pr_info("efuse read ret %d\n", msg->ret); } } else if(EFUSE_WRITE == (u32)msg->opt) { if(1 == efuse_debug_flag) { pr_info("efuse write start group %d length %d.\n", msg->start, msg->len); for(i = 0;i < msg->len;i++) { pr_info("efuse buf[%d] is 0x%x.\n", i, msg->buf[i]); } } msg->ret = bsp_efuse_write(msg->buf, msg->start,msg->len); if(1 == efuse_debug_flag) { pr_info("efuse write ret %d.\n", msg->ret); } } else { msg->ret = EFUSE_ERROR; } length = bsp_icc_send(ICC_CPU_MODEM, channel_id, (unsigned char*)msg, sizeof(EFUSE_DATA_STRU)); if(length != (int)sizeof(EFUSE_DATA_STRU)) { efuse_print_error("send len(%x) != expected len(%lu).\n", length, (unsigned long)sizeof(EFUSE_DATA_STRU)); return; } }
/****************************************************************************** * 函 数 名: do_burn * 功能描述: 将flash spec信息烧写到efuse * 输入参数: @spec:存放flash info * 输出参数: 无 * 返 回 值: 0 - 成功; 非0 - 失败 * 函数说明: *******************************************************************************/ static s32 do_burn(struct nand_spec *spec) { s32 ret = ERROR; u32 efuse_nand_info_addr = EFUSE_NANDC_GROUP_OFFSET; u32 read_value; u32 value = 0; /* param error */ if(!spec) { PRINT_MSG("Param failed\n"); goto erro; } /* make value */ switch(spec->pagenumperblock) /* add page num per block */ { case NANDC_BLOCK_64PAGE: value |= EFUSE_NANDC_BLOCKSIZE_64PAGE; break; case NANDC_BLOCK_128PAGE: value |= EFUSE_NANDC_BLOCKSIZE_128PAGE; break; default: break; } PRINT_MSG("Add block size: 0x%x\n", value); /*lint -save -e30, -e142*/ switch(spec->ecctype) /* add ecc type */ { case NANDC_ECC_NONE: value |= EFUSE_NANDC_ECCTYPE_NONE; break; case NANDC_ECC_1BIT: value |= EFUSE_NANDC_ECCTYPE_1BIT; break; case NANDC_ECC_4BIT: value |= EFUSE_NANDC_ECCTYPE_4BIT; break; case NANDC_ECC_8BIT: value |= EFUSE_NANDC_ECCTYPE_8BIT; break; default: break; } /*lint -restore*/ PRINT_MSG("Add ecc type: 0x%x\n", value); switch(spec->pagesize) /* add page size */ { case NANDC_SIZE_HK: value |= EFUSE_NANDC_PAGESIZE_hK; break; case NANDC_SIZE_2K: value |= EFUSE_NANDC_PAGESIZE_2K; break; case NANDC_SIZE_4K: value |= EFUSE_NANDC_PAGESIZE_4K; break; case NANDC_SIZE_8K: value |= EFUSE_NANDC_PAGESIZE_8K; break; default: break; } PRINT_MSG("Add page size: 0x%x\n", value); switch(spec->addrnum) /* add addr num */ { case NANDC_ADDRCYCLE_4: value |= EFUSE_NANDC_ADDRNUM_4CYCLE; break; case NANDC_ADDRCYCLE_5: value |= EFUSE_NANDC_ADDRNUM_5CYCLE; break; default: break; } PRINT_MSG("Add addr num: 0x%x\n", value); /* set burn flag */ value |= EFUSE_NANDC_BURNFLAG_HADBURN; PRINT_MSG("Add burn flag: 0x%x\n", value); /* set configure nandc from efuse */ value |= EFUSE_CONF_FROM_EFUSE; PRINT_MSG("Add conf flag: 0x%x\n", value); /* write info */ ret = bsp_efuse_write(&value, efuse_nand_info_addr, EFUSE_NANDC_GROUP_LENGTH); if(ret) { PRINT_MSG("EFuse write failed\n"); goto erro; } /* read and compare */ ret = bsp_efuse_read(&read_value, efuse_nand_info_addr, EFUSE_NANDC_GROUP_LENGTH); if(ret) { PRINT_MSG("EFuse read failed\n"); goto erro; } if(read_value != value) { PRINT_MSG("EFuse value cmp error, write value: 0x%x, read value 0x%x\n", value, read_value); ret = ERROR; goto erro; } PRINT_MSG("SUCCESS: write nandc info successful\n"); return OK; erro: return ret; }
s32 startSecure(void) { s32 sec_err_code = SEC_OK; u8 flag = 0; u8 * m3boot_ram_addr = NULL; u32 ulEfuseRootCaHash[SHA256_HASH_SIZE] = {0}; /*用来存放SHA256值的临时buffer*/ u32 efuse_security_flag = 0; u32 md5_hash[MD5_HASH_SIZE] = {0}; sec_err_code = secureAlreadyUse(&flag); if(sec_err_code) { return -1; } if( SECURE_ENABLE == flag ) /* has been written */ { return SEC_OK; } sec_err_code = secureSupport(&flag); if(SEC_OK != sec_err_code) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]check Secure support error!\n"); return sec_err_code; } if(SECURE_NOT_SUPPORT == flag) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]Secure not support!\n"); return SEC_ERROR_IMG_SECURY_NOT_SUPPORT; } m3boot_ram_addr = (u8*)osl_malloc(ROOT_CA_LEN); if(!m3boot_ram_addr) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "[SEC ERROR]NO mem error!\n"); return -1; } sec_err_code = BSP_mass_read("m3boot", /*P531_M3_LEN_INDEX + sizeof(u32)*/ROOT_CA_INDEX, ROOT_CA_LEN, m3boot_ram_addr); if(SEC_OK != sec_err_code) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "BSP_mass_read error!\n"); return sec_err_code; } #if 0//for debug, print rootca printf("\n"); for(i = 0; i < ROOT_CA_LEN / 4; i += 4) { printf("%X\n", *(unsigned long *)(m3boot_ram_addr + i)); } printf("\n"); #endif /*计算ROOT CA HASH*/ sec_err_code = kdf_sha256(m3boot_ram_addr, ROOT_CA_LEN, (u8*)ulEfuseRootCaHash); if(SEC_OK != sec_err_code) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "\r\ncalc RootCa sha1 err!\n"); return SEC_ERROR_SHA_ERR; } /*计算HASH值的MD5值*/ sec_err_code = encrypt_lock_md5_data(ulEfuseRootCaHash, SHA256_HASH_SIZE * sizeof(u32), md5_hash); if(sec_err_code) { return -1; } sec_err_code = bsp_efuse_read(&efuse_security_flag, EFUSE_GRP_SECURITY, 1); if( SEC_OK != sec_err_code) { bsp_trace(BSP_LOG_LEVEL_ERROR, BSP_MODU_SECURITY, "startSecure: run efuse_read error!\n"); return SEC_ERROR_EFUSE_READ_ERR; } efuse_security_flag |= EFUSEC_SEC_EN; /* write RootCA hash */ if( SEC_OK != bsp_efuse_write( md5_hash, EFUSE_GRP_ROOT_CA, 4 ) ) { return -1; } /* Last step, enable security boot */ if( SEC_OK != bsp_efuse_write( (u32 *)&efuse_security_flag, EFUSE_GRP_SECURITY, 1 ) ) { return -1; } bsp_trace(BSP_LOG_LEVEL_INFO, BSP_MODU_SECURITY, "\r\nstartSecure SUCC!\r\n", 0, 0, 0, 0, 0, 0 ); return 0; }