/***************************************************************************** * 函 数 名 : apSecChk * * 功能描述 : AP封装的安全校验函数 * * 输入参数 : * 输出参数 : * * 返 回 值 : * * 其它说明 : * *****************************************************************************/ INT32 apSecChk( UINT32 ulImgAddr ) { INT32 iRet; volatile tOcrShareData *pShareData = (tOcrShareData *)M3_TCM_SHARE_DATA_ADDR; if(BL_CHECK_INSTRUCTION != *(volatile UINT32 *)(ulImgAddr + BL_CHECK_ADDR_OFFSET)) { /* 镜像未烧入或错误镜像,返回错误供调用者处理 */ print_info("\r\nimage not program!" ); return SEC_NO_IMAGE; } if(!pShareData->bSecEn) { print_info("\r\nUnSec_boot!" ); return SEC_SUCCESS; } iRet = secCheck(ulImgAddr, IMAGE_TYPE_BOOTLOAD); switch(iRet) { case SEC_SUCCESS: /*安全校验通过*/ print_info("\r\nSec check ok!" ); /*lint !e616*/ break; /* 进入下一case运行BootLoader */ case SEC_EFUSE_NOT_WRITE: /*lint !e825*/ /*EFUSE 未烧写*/ break; case SEC_SHA_CALC_ERROR: /* Hash计算不通过 */ case SEC_OEMCA_ERROR: /* OEM CA校验不通过 */ case SEC_IMAGE_ERROR: /* 映像校验不通过 */ case SEC_ROOT_CA_ERROR: /* 根CA校验错误 */ case SEC_IMAGE_LEN_ERROR:/*安全版本长度错误*/ print_info("\r\nSec check err!" ); break; case SEC_EFUSE_READ_ERROR: /*Efuse读取失败,使用看门狗复位,再次尝试读取*/ print_info("\r\nEfuse read err, reboot..."); /* Efuse读取失败,复位单板 */ setErrno(SYS_ERR_EFUSE_READ); wdtRebootDelayMs(TIME_DELAY_MS_2000_FOR_EFUSE_READERR); break; default: while(1) /*lint !e716*/ { print_info_with_u32("\r\nunhandered ret:",(UINT32)iRet); delay(1000*1000); /* 延时1s */ } /*break; */ /*for pc lint*/
/***************************************************************************** * 函 数 名 : nandReadBl * * 功能描述 : 根据实际长度读取BootLoader * * 输入参数 : dest BootLoader读取的目的地 * 输出参数 : * * 返 回 值 : OK 读取成功 * NAND_ECC_ERR ECC出现不可纠正的错误 * SEC_IMAGE_LEN_ERROR 长度错误 * * 其它说明 : * *****************************************************************************/ int nandReadBl( UINT32 dest ) { UINT32 blLen; UINT32 ulEccType; /* 配置IO复用,NAND取默认配置。*/ NF_IOS_SYS_CONFIG(); /* 配置脉宽为16 */ OUTREG32(NANDC_PWIDTH, 0x555); delay(10); /* 检查是否为Boot模式,如果不是,则直接重启,再次尝试读取 */ if(NANDC_OPMODE_BOOT != (INREG32(NANDC_CON) & NANDC_OPMODE_MASK)) { print_info("\r\nnot in boot mode,reboot to try..."); setErrno(NAND_NO_IN_BOOTMODE); wdtRebootDelayMs(TIME_DELAY_MS_6000_FOR_NF_OPBOOT); } /* 获取BootLoader长度 */ blLen = *(volatile UINT32 *)(FLASH_BOOT_ADDR+BL_LEN_INDEX); /* 获取ECC Type */ ulEccType = INREG32(NANDC_CON) & NAND_ECC_TYPE_MASK; /* 使能ECC情况下,产生ECC不可纠正的错误 */ if((NAND_ECC_TYPE_0 != ulEccType) && (INREG32(NANDC_INTS) & ECC_ERR_INVALID)) { print_info("\r\necc err!"); return NAND_ECC_ERR; } /* 判断长度是否合法:不为零/字对齐/不翻转/不过大 */ /* 0x1234ABCD - read retry failed */ /* 0xABCD1234 - all block(0 to 7) is bad */ if((0 == blLen) || (blLen % 4) || (blLen + IDIO_LEN + OEM_CA_LEN + IDIO_LEN < blLen) || (blLen + IDIO_LEN + OEM_CA_LEN + IDIO_LEN > BOOTLOAD_SIZE_MAX)) { print_info_with_u32("\r\nBL len err:", blLen); return SEC_IMAGE_LEN_ERROR; } /* 加上镜像签名、OEM CA和OEM CA签名的长度 (安全校验时才添加)*/ blLen += IDIO_LEN + OEM_CA_LEN + IDIO_LEN; delay(10); /* Boot模式下直接读取整个BootLoader */ memcpy((void*)dest, (void*)FLASH_BOOT_ADDR, blLen); return OK; }
void hsicBoot() { /* 软标志有效或自举管脚为低电平,进入自举流程*/ hsic_works(); /* USB自举退出,复位系统,重新尝试 */ print_info("\r\nHSIC_boot returns, reboot..." ); setErrno(SYS_ERR_HSIC_BOOT_RETURNS); wdtRebootDelayMs(TIME_DELAY_MS_1000_FOR_UBOOT_RETURN); }
/***************************************************************************** * 函 数 名 : usbBoot * * 功能描述 : usb自举 * * 输入参数 : * 输出参数 : * * 返 回 值 : * * 其它说明 : * *****************************************************************************/ void usbBoot() { print_info("\r\nUSB_boot!" ); /* 软标志有效或自举管脚为低电平,进入自举流程*/ usb3_driver_init(); /* USB自举退出,复位系统,重新尝试 */ print_info("\r\nUSB_boot returns, reboot..." ); setErrno(SYS_ERR_USB_BOOT_RETURNS); wdtRebootDelayMs(TIME_DELAY_MS_1000_FOR_UBOOT_RETURN); }
static void bthSetErrno (DWORD error, const char *action, const DWORD *exceptions) { if (exceptions) { const DWORD *exception = exceptions; while (*exception != NO_ERROR) { if (error == *exception) goto isException; exception += 1; } } logWindowsError(error, action); isException: setErrno(error); }
static void setWindowsTransferResult (OperationEntry *operation, DWORD success, DWORD count) { TransferExtension *extension = operation->extension; if (success) { extension->length += count; } else { DWORD error = GetLastError(); if ((error == ERROR_HANDLE_EOF) || (error == ERROR_BROKEN_PIPE)) { extension->direction.input.end = 1; } else { setErrno(error); operation->error = errno; if (error == ERROR_IO_PENDING) return; if (error == ERROR_IO_INCOMPLETE) return; } } operation->finished = 1; }
/***************************************************************************** * 函 数 名 : secBoot * * 功能描述 : 安全启动C入口函数 * * 输入参数 : * 输出参数 : * * 返 回 值 : * * 其它说明 : * *****************************************************************************/ void secBoot(void) { volatile UINT32 ulBootModeVal = 0x00; volatile tOcrShareData *pShareData = (tOcrShareData*)M3_SRAM_SHARE_DATA_ADDR; int retVal = 0x00; int BOOT_RST_Addr = 0x00; #if PLATFORM==PLATFORM_PORTING //testEfuseRead(); //testHash256(); #endif /* 初始化 */ timerInit(); pShareData->errno = 0; pShareData->SHA256Hash = NULL; pShareData->RSA = NULL; pShareData->idioIdentify = NULL; pShareData->bSecEn = FALSE; pShareData->bRootCaInited = FALSE; pShareData->pRootKey = NULL; pShareData->ulOcrInitedFlag = FALSE; pShareData->bsp_nand_get_spec_and_save = NULL; /* 读取Efuse安全校验配置,获取安全标志 */ if(EFUSEC_SEC_EN == (INREG32(EFUSEC_HW_CFG) & EFUSEC_SEC_EN_MASK)) { pShareData->bSecEn = TRUE; } /*判断USB自举软件标志是否有效*/ if((AUTO_ENUM_FLAG_VALUE == pShareData->ulEnumFlag) || (SC_AUTO_ENUM_EN == (INREG32(SC_STAT0) & SC_AUTO_ENUM_EN_BITMASK))) { /* 软标志有效或自举管脚为低电平,先清除标志,再进入自举流程*/ /*pShareData->ulEnumFlag = 0;*/ /* 不清除标志,供探针程序检查自举原因 */ usbBoot(); } /*读取BOOTMODE*/ ulBootModeVal = INREG32(SC_STAT0) & SC_BOOTMODE_BITMASK; switch(ulBootModeVal) { case BOOT_MODE_NAND_ID: { print_info("\r\nNF id boot!" ); retVal = nandReadBl(M3_TCM_BL_ADDR, NAND_PARSE_ID_MODE, &(pShareData->nandspec)); break; } case BOOT_MODE_NAND_BOOT: { print_info("\r\nNF boot only!" ); /* Nand默认在Boot模式下,直接拷贝bootload映像 */ retVal = nandReadBl(M3_TCM_BL_ADDR, ONLY_NAND_BOOT_MODE, &(pShareData->nandspec)); break; } case BOOT_MODE_NAND_EFUSE: { print_info("\r\nNF efuse boot!" ); retVal = nandReadBl(M3_TCM_BL_ADDR, EFUSE_BOOT_MODE, &(pShareData->nandspec)); break; } #if HSIC_CONFIG==YES case BOOT_MODE_AP_HSIC: { print_info("\r\nHSIC boot!" ); /*通过HSIC将bootload映像读取*/ hsicBoot(); break; } #endif #if SPI_CONFIG==YES case BOOT_MODE_SPI: { print_info("\r\nSPI boot!" ); /*从SPI中将bootload映像读取*/ retVal = spiDevReadBl((UINT8*)M3_TCM_BL_ADDR); break; } #endif #if EMMC_CONFIG==YES case BOOT_MODE_EMMC: { print_info("\r\nEMMC boot!" ); /*搬运bootload映像*/ retVal = emmc_read_bootloader(M3_TCM_BL_ADDR); break; } #endif #if HSUART_CONFIG==YES case BOOT_MODE_AP_HSUART: { print_info("\r\nHSUART boot!" ); /* 不再返回 */ retVal = apDlMain(M3_TCM_BL_ADDR); /* 防止apDlMain返回,这里打印错误 */ print_info_with_u32("\r\napDlMain exec err, ret:" , (UINT32)retVal); setErrno(SYS_ERR_AP_DL_RETURNS); /* 延时复位 */ wdtRebootDelayMs(TIME_DELAY_MS_4000_FOR_AP_RETURNS); break; /*lint !e527*/ } #endif default: { #if PLATFORM==PLATFORM_PORTING /* PORTING版本使用此模式烧写EFUSE */ print_info_with_u32("\r\nbootmode err, will write efuse on porting..." , ulBootModeVal); testEfuseWrite(); usbBoot(); break; #else /* 复位,以防止Stick形态没有串口,从复位可以得知错误 */ print_info_with_u32("\r\nbootmode err:" , (ulBootModeVal>>SC_BOOTMODE_BITPOS)); setErrno(SYS_ERR_BOOT_MODE); /* 延时复位 */ wdtRebootDelayMs(TIME_DELAY_MS_3000_FOR_BOOT_MODE); break; #endif } } if(OK != retVal) { print_info_with_u32("\r\nBL read err, ret:", (UINT32)retVal); setErrno(retVal); usbBoot(); } /*判断FLASH /E2/MMC是否烧入映像*/ if(BL_CHECK_INSTRUCTION != *(volatile UINT32 *)BL_CHECK_ADDR) { /*映像未烧入,向AP返回Nack, 或跳入USB自举流程*/ print_info("\r\nimage not program!" ); setErrno(SEC_NO_IMAGE); usbBoot(); } ocrShareSave(); /*非安全启动,直接运行*/ if(!pShareData->bSecEn) { print_info("\r\nUnSec_boot!" ); /*非安全,跳入TCM执行*/ BOOT_RST_Addr = *(volatile UINT32 *)BOOT_RST_ADDR_PP; go((FUNCPTR)(M3_TCM_BL_ADDR + BOOT_RST_Addr)); } /*安全启动,进行安全校验*/ retVal = secCheck((UINT32)M3_TCM_BL_ADDR, IMAGE_TYPE_BOOTLOAD); #ifdef START_TIME_TEST print_info_with_u32("\r\ntime(ms):", (TIMER5_INIT_VALUE - INREG32(TIMER5_REGOFF_VALUE))/MS_TICKS); #endif switch(retVal) { case SEC_SUCCESS: /*安全校验通过*/ print_info("\r\nSec check ok!" ); /*lint !e616*/ /* 进入下一case运行BootLoader */ case SEC_EFUSE_NOT_WRITE: /*lint !e825*/ /*EFUSE 未烧写*/ /* 跳到TCM mem执行BOOTLOAD */ BOOT_RST_Addr = *(volatile UINT32 *)BOOT_RST_ADDR_PP; go((FUNCPTR)(M3_TCM_BL_ADDR + BOOT_RST_Addr)); break; case SEC_SHA_CALC_ERROR: /* Hash计算不通过 */ case SEC_OEMCA_ERROR: /* OEM CA校验不通过 */ case SEC_IMAGE_ERROR: /* 映像校验不通过 */ case SEC_ROOT_CA_ERROR: /* 根CA校验错误 */ case SEC_IMAGE_LEN_ERROR:/*安全版本长度错误*/ print_info("\r\nSec check err!" ); setErrno(retVal); usbBoot(); break; case SEC_EFUSE_READ_ERROR: /*Efuse读取失败,使用看门狗复位,再次尝试读取*/ print_info("\r\nEfuse read err, reboot..."); setErrno(SYS_ERR_EFUSE_READ); wdtRebootDelayMs(TIME_DELAY_MS_2000_FOR_EFUSE_READERR); break; default: print_info_with_u32("\r\nunhandered ret:",(UINT32)retVal); setErrno(SYS_ERR_SEC_UNKNOWN_RET); /* 延时1s */ wdtRebootDelayMs(TIME_DELAY_MS_5000_FOR_SEC_UNKNOWN_RET); /*break; */ /*for pc lint*/ }