sint8 wait_for_firmware_start(uint8 arg) { sint8 ret = M2M_SUCCESS; uint32 reg = 0, cnt = 0; volatile uint32 regAddress = NMI_STATE_REG; volatile uint32 checkValue = M2M_FINISH_INIT_STATE; if(2 == arg) { regAddress = NMI_REV_REG; checkValue = M2M_ATE_FW_IS_UP_VALUE; } else { /*bypass this step*/ } while (checkValue != reg) { nm_bsp_sleep(2); /* TODO: Why bus error if this delay is not here. */ M2M_DBG("%x %x %x\n",(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x14A0)); reg = nm_read_reg(regAddress); if(++cnt > TIMEOUT) { M2M_DBG("Time out for wait firmware Run\n"); ret = M2M_ERR_INIT; goto ERR; } } if(M2M_FINISH_INIT_STATE == checkValue) { nm_write_reg(NMI_STATE_REG, 0); } ERR: return ret; }
sint8 wait_for_bootrom(uint8 arg) { sint8 ret = M2M_SUCCESS; uint32 reg = 0, cnt = 0; reg = 0; while(1) { reg = nm_read_reg(0x1014); /* wait for efuse loading done */ if (reg & 0x80000000) { break; } nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */ } reg = nm_read_reg(M2M_WAIT_FOR_HOST_REG); reg &= 0x1; /* check if waiting for the host will be skipped or not */ if(reg == 0) { reg = 0; while(reg != M2M_FINISH_BOOT_ROM) { nm_bsp_sleep(1); reg = nm_read_reg(BOOTROM_REG); if(++cnt > TIMEOUT) { M2M_DBG("failed to load firmware from flash.\n"); ret = M2M_ERR_INIT; goto ERR2; } } } if(2 == arg) { nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE); } else { /*bypass this step*/ } if(REV(nmi_get_chipid()) == REV_3A0) { chip_apply_conf(rHAVE_USE_PMU_BIT); } else { chip_apply_conf(0); } nm_write_reg(BOOTROM_REG,M2M_START_FIRMWARE); #ifdef __ROM_TEST__ rom_test(); #endif /* __ROM_TEST__ */ ERR2: return ret; }
/** * @fn spi_flash_rdid * @brief Read SPI Flash ID * @return SPI FLash ID */ static uint32 spi_flash_rdid(void) { unsigned char cmd[1]; uint32 reg = 0; uint32 cnt = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x9f; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; if(++cnt > 500) { ret = M2M_ERR_INIT; break; } } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); M2M_PRINT("Flash ID %x \n",(unsigned int)reg); return reg; }
/** * @fn NMI_API sint8 hif_deinit(void * arg); * @brief To Deinitialize HIF layer. * @param [in] arg * Pointer to the arguments. * @return The function shall return ZERO for successful operation and a negative value otherwise. */ sint8 hif_deinit(void * arg) { sint8 ret = M2M_SUCCESS; #if 0 uint32 reg = 0, cnt=0; while (reg != M2M_DISABLE_PS) { nm_bsp_sleep(1); reg = nm_read_reg(STATE_REG); if(++cnt > 1000) { M2M_DBG("failed to stop power save\n"); break; } } #endif ret = hif_chip_wake(); gu8ChipMode = 0; gu8ChipSleep = 0; gu8HifSizeDone = 0; gu8Interrupt = 0; pfWifiCb = NULL; pfIpCb = NULL; pfOtaCb = NULL; pfHifCb = NULL; return ret; }
static sint8 spi_flash_probe(uint32 * u32FlashId) { sint8 ret = M2M_SUCCESS; uint32 pin_mux_0; uint32 orig_pin_mux_0; uint32 flashid; pin_mux_0 = nm_read_reg(0x1408); orig_pin_mux_0 = pin_mux_0; if( (orig_pin_mux_0 & 0xffff000) != 0x1111000) { /* Select PINMUX to use SPI MASTER */ pin_mux_0 &= ~0xffff000; pin_mux_0 |= 0x1111000; nm_write_reg(0x1408, pin_mux_0); } flashid = spi_flash_rdid(); if( (orig_pin_mux_0 & 0xffff000) != 0x1111000) { nm_write_reg(0x1408, orig_pin_mux_0); } *u32FlashId = flashid; return ret; }
static uint32 spi_flash_rdid(void) { unsigned char cmd[1]; uint32 reg; cmd[0] = 0x9f; nm_write_reg(SPI_FLASH_DATA_CNT, 4); nm_write_reg(SPI_FLASH_BUF1, cmd[0]); nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); while(nm_read_reg(SPI_FLASH_TR_DONE) != 1); reg = nm_read_reg(DUMMY_REGISTER); M2M_PRINT("Flash id %x \n",reg); return reg; }
void nmi_update_pll(void) { uint32 pll; pll = nm_read_reg(0x1428); pll &= ~0x1ul; nm_write_reg(0x1428, pll); pll |= 0x1ul; nm_write_reg(0x1428, pll); }
void nmi_set_sys_clk_src_to_xo(void) { uint32 val32; /* Switch system clock source to XO. This will take effect after nmi_update_pll(). */ val32 = nm_read_reg(0x141c); val32 |= (1 << 2); nm_write_reg(0x141c, val32); /* Do PLL update */ nmi_update_pll(); }
static void spi_flash_leave_low_power_mode(void) { volatile unsigned long tmp; unsigned char* cmd = (unsigned char*) &tmp; cmd[0] = 0xab; nm_write_reg(SPI_FLASH_DATA_CNT, 0); nm_write_reg(SPI_FLASH_BUF1, cmd[0]); nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); nm_write_reg(SPI_FLASH_DMA_ADDR, 0); nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1 << 7)); while(nm_read_reg(SPI_FLASH_TR_DONE) != 1); }
/** * @fn spi_flash_read_security_reg * @brief Read security register * @return Security register value */ static uint8 spi_flash_read_security_reg(void) { uint8 cmd[1]; uint32 reg; sint8 ret = M2M_SUCCESS; cmd[0] = 0x2b; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 1); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); return (sint8)reg & 0xff; }
/** * @fn spi_flash_read_status_reg * @brief Read status register * @param[OUT] val value of status reg * @return Status of execution */ static sint8 spi_flash_read_status_reg(uint8 * val) { sint8 ret = M2M_SUCCESS; uint8 cmd[1]; uint32 reg; cmd[0] = 0x05; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); *val = (uint8)(reg & 0xff); return ret; }
void BigInt_ModExp ( uint8 *pu8X, uint16 u16XSize, uint8 *pu8E, uint16 u16ESize, uint8 *pu8M, uint16 u16MSize, uint8 *pu8R, uint16 u16RSize ) { uint32 u32Reg; uint8 au8Tmp[780] = {0}; uint32 u32XAddr = SHARED_MEM_BASE; uint32 u32MAddr; uint32 u32EAddr; uint32 u32RAddr; uint8 u8EMswBits = 32; uint32 u32Mprime = 0x7F; uint16 u16XSizeWords,u16ESizeWords; uint32 u32Exponent; u16XSizeWords = (u16XSize + 3) / 4; u16ESizeWords = (u16ESize + 3) / 4; u32MAddr = u32XAddr + (u16XSizeWords * 4); u32EAddr = u32MAddr + (u16XSizeWords * 4); u32RAddr = u32EAddr + (u16ESizeWords * 4); /* Reset the core. */ u32Reg = 0; u32Reg |= BIGINT_MISC_CTRL_CTL_RESET; u32Reg = nm_read_reg(BIGINT_MISC_CTRL); u32Reg &= ~BIGINT_MISC_CTRL_CTL_RESET; u32Reg = nm_read_reg(BIGINT_MISC_CTRL); nm_write_block(u32RAddr,au8Tmp, u16RSize); /* Write Input Operands to Chip Memory. */ /*------- X -------*/ FlipBuffer(pu8X,au8Tmp,u16XSize); nm_write_block(u32XAddr,au8Tmp,u16XSizeWords * 4); /*------- E -------*/ m2m_memset(au8Tmp, 0, sizeof(au8Tmp)); FlipBuffer(pu8E, au8Tmp, u16ESize); nm_write_block(u32EAddr, au8Tmp, u16ESizeWords * 4); u32Exponent = GET_UINT32(au8Tmp, (u16ESizeWords * 4) - 4); while((u32Exponent & NBIT31)== 0) { u32Exponent <<= 1; u8EMswBits --; } /*------- M -------*/ m2m_memset(au8Tmp, 0, sizeof(au8Tmp)); FlipBuffer(pu8M, au8Tmp, u16XSize); nm_write_block(u32MAddr, au8Tmp, u16XSizeWords * 4); /* Program the addresses of the input operands. */ nm_write_reg(BIGINT_ADDR_X, u32XAddr); nm_write_reg(BIGINT_ADDR_E, u32EAddr); nm_write_reg(BIGINT_ADDR_M, u32MAddr); nm_write_reg(BIGINT_ADDR_R, u32RAddr); /* Mprime. */ nm_write_reg(BIGINT_M_PRIME,u32Mprime); /* Length. */ u32Reg = (u16XSizeWords & 0xFF); u32Reg += ((u16ESizeWords & 0xFF) << 8); u32Reg += (u8EMswBits << 16); nm_write_reg(BIGINT_LENGTH,u32Reg); /* CTRL Register. */ u32Reg = nm_read_reg(BIGINT_MISC_CTRL); u32Reg ^= BIGINT_MISC_CTRL_CTL_START; u32Reg |= BIGINT_MISC_CTRL_CTL_FORCE_BARRETT; //u32Reg |= BIGINT_MISC_CTRL_CTL_M_PRIME_VALID; #if ENABLE_FLIPPING == 0 u32Reg |= BIGINT_MISC_CTRL_CTL_MSW_FIRST; #endif nm_write_reg(BIGINT_MISC_CTRL,u32Reg); /* Wait for computation to complete. */ while(1) { u32Reg = nm_read_reg(BIGINT_IRQ_STS); if(u32Reg & BIGINT_IRQ_STS_DONE) { break; } } nm_write_reg(BIGINT_IRQ_STS,0); m2m_memset(au8Tmp, 0, sizeof(au8Tmp)); nm_read_block(u32RAddr, au8Tmp, u16RSize); FlipBuffer(au8Tmp, pu8R, u16RSize); }
sint8 m2m_crypto_sha256_hash_finish(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Sha256Digest) { sint8 s8Ret = M2M_ERR_FAIL; tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt; if(pstrSHA256 != NULL) { uint32 u32ReadAddr; uint32 u32WriteAddr = SHARED_MEM_BASE; uint32 u32Addr = u32WriteAddr; uint16 u16Offset; uint16 u16PaddingLength; uint16 u16NBlocks = 1; uint32 u32RegVal = 0; uint32 u32Idx,u32ByteIdx; uint32 au32Digest[M2M_SHA256_DIGEST_LEN / 4]; uint8 u8IsDone = 0; nm_write_reg(SHA256_CTRL,u32RegVal); u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK; nm_write_reg(SHA256_CTRL,u32RegVal); if(pstrSHA256->u8InitHashFlag) { pstrSHA256->u8InitHashFlag = 0; u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK; } /* Calculate the offset of the last data byte in the current block. */ u16Offset = (uint16)(pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE); /* Add the padding byte 0x80. */ pstrSHA256->au8CurrentBlock[u16Offset ++] = 0x80; /* Calculate the required padding to complete one Hash Block Size. */ u16PaddingLength = SHA_BLOCK_SIZE - u16Offset; m2m_memset(&pstrSHA256->au8CurrentBlock[u16Offset], 0, u16PaddingLength); /* If the padding count is not enough to hold 64-bit representation of the total input message length, one padding block is required. */ if(u16PaddingLength < 8) { nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); u32Addr += SHA_BLOCK_SIZE; m2m_memset(pstrSHA256->au8CurrentBlock, 0, SHA_BLOCK_SIZE); u16NBlocks ++; } /* pack the length at the end of the padding block */ PUTU32(pstrSHA256->u32TotalLength << 3, pstrSHA256->au8CurrentBlock, (SHA_BLOCK_SIZE - 4)); u32ReadAddr = u32WriteAddr + (u16NBlocks * SHA_BLOCK_SIZE); nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); nm_write_reg(SHA256_DATA_LENGTH, (u16NBlocks * SHA_BLOCK_SIZE)); nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr); nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr); u32RegVal |= SHA256_CTRL_START_CALC_MASK; u32RegVal |= SHA256_CTRL_WR_BACK_HASH_VALUE_MASK; u32RegVal &= ~(0x7UL << 8); u32RegVal |= (0x2UL << 8); nm_write_reg(SHA256_CTRL,u32RegVal); /* 5. Wait for done_intr */ while(!u8IsDone) { u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS); u8IsDone = u32RegVal & NBIT0; } nm_read_block(u32ReadAddr, (uint8*)au32Digest, 32); /* Convert the output words to an array of bytes. */ u32ByteIdx = 0; for(u32Idx = 0; u32Idx < (M2M_SHA256_DIGEST_LEN / 4); u32Idx ++) { pu8Sha256Digest[u32ByteIdx ++] = BYTE_3(au32Digest[u32Idx]); pu8Sha256Digest[u32ByteIdx ++] = BYTE_2(au32Digest[u32Idx]); pu8Sha256Digest[u32ByteIdx ++] = BYTE_1(au32Digest[u32Idx]); pu8Sha256Digest[u32ByteIdx ++] = BYTE_0(au32Digest[u32Idx]); } s8Ret = M2M_SUCCESS; } return s8Ret; }
sint8 m2m_crypto_sha256_hash_update(tstrM2mSha256Ctxt *pstrSha256Ctxt, uint8 *pu8Data, uint16 u16DataLength) { sint8 s8Ret = M2M_ERR_FAIL; tstrSHA256HashCtxt *pstrSHA256 = (tstrSHA256HashCtxt*)pstrSha256Ctxt; if(pstrSHA256 != NULL) { uint32 u32ReadAddr; uint32 u32WriteAddr = SHARED_MEM_BASE; uint32 u32Addr = u32WriteAddr; uint32 u32ResidualBytes; uint32 u32NBlocks; uint32 u32Offset; uint32 u32CurrentBlock = 0; uint8 u8IsDone = 0; /* Get the remaining bytes from the previous update (if the length is not block aligned). */ u32ResidualBytes = pstrSHA256->u32TotalLength % SHA_BLOCK_SIZE; /* Update the total data length. */ pstrSHA256->u32TotalLength += u16DataLength; if(u32ResidualBytes != 0) { if((u32ResidualBytes + u16DataLength) >= SHA_BLOCK_SIZE) { u32Offset = SHA_BLOCK_SIZE - u32ResidualBytes; m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset); pu8Data += u32Offset; u16DataLength -= u32Offset; nm_write_block(u32Addr, pstrSHA256->au8CurrentBlock, SHA_BLOCK_SIZE); u32Addr += SHA_BLOCK_SIZE; u32CurrentBlock = 1; } else { m2m_memcpy(&pstrSHA256->au8CurrentBlock[u32ResidualBytes], pu8Data, u16DataLength); u16DataLength = 0; } } /* Get the number of HASH BLOCKs and the residual bytes. */ u32NBlocks = u16DataLength / SHA_BLOCK_SIZE; u32ResidualBytes = u16DataLength % SHA_BLOCK_SIZE; if(u32NBlocks != 0) { nm_write_block(u32Addr, pu8Data, (uint16)(u32NBlocks * SHA_BLOCK_SIZE)); pu8Data += (u32NBlocks * SHA_BLOCK_SIZE); } u32NBlocks += u32CurrentBlock; if(u32NBlocks != 0) { uint32 u32RegVal = 0; nm_write_reg(SHA256_CTRL, u32RegVal); u32RegVal |= SHA256_CTRL_FORCE_SHA256_QUIT_MASK; nm_write_reg(SHA256_CTRL, u32RegVal); if(pstrSHA256->u8InitHashFlag) { pstrSHA256->u8InitHashFlag = 0; u32RegVal |= SHA256_CTRL_INIT_SHA256_STATE_MASK; } u32ReadAddr = u32WriteAddr + (u32NBlocks * SHA_BLOCK_SIZE); nm_write_reg(SHA256_DATA_LENGTH, (u32NBlocks * SHA_BLOCK_SIZE)); nm_write_reg(SHA256_START_RD_ADDR, u32WriteAddr); nm_write_reg(SHA256_START_WR_ADDR, u32ReadAddr); u32RegVal |= SHA256_CTRL_START_CALC_MASK; u32RegVal &= ~(0x7 << 8); u32RegVal |= (2 << 8); nm_write_reg(SHA256_CTRL, u32RegVal); /* 5. Wait for done_intr */ while(!u8IsDone) { u32RegVal = nm_read_reg(SHA256_DONE_INTR_STS); u8IsDone = u32RegVal & NBIT0; } } if(u32ResidualBytes != 0) { m2m_memcpy(pstrSHA256->au8CurrentBlock, pu8Data, u32ResidualBytes); } s8Ret = M2M_SUCCESS; } return s8Ret; }