/*****************************************************************************
* 函 数 名  : 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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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*/

    }