void rom_test() { uint8 *pu8TextSec; FILE *fp; uint32 u32CodeSize = 0; nm_bsp_sleep(1000); /* Read text section. */ fp = fopen(ROM_FIRMWARE_FILE,"rb"); if(fp) { /* Get the code size. */ fseek(fp, 0L, SEEK_END); u32CodeSize = ftell(fp); fseek(fp, 0L, SEEK_SET); pu8TextSec = (uint8*)malloc(u32CodeSize); if(pu8TextSec != NULL) { M2M_INFO("Code Size %f\n",u32CodeSize / 1024.0); fread(pu8TextSec, u32CodeSize, 1, fp); nm_write_block(CODE_BASE, pu8TextSec, (uint16)u32CodeSize); //nm_read_block(CODE_BASE, tmpv, sz); fclose(fp); free(pu8TextSec); } } #if 0 uint8 *pu8DataSec; uint32 u32DataSize = 0; /* Read data section. */ fp = fopen(ROM_DATA_FILE,"rb"); if(fp) { /* Get the data size. */ fseek(fp, 0L, SEEK_END); u32DataSize = ftell(fp); fseek(fp, 0L, SEEK_SET); pu8DataSec = (uint8*)malloc(u32DataSize); if(pu8DataSec != NULL) { M2M_INFO("Data Size %f\n",u32DataSize / 1024.0); fread(pu8DataSec, u32DataSize, 1, fp); nm_write_block(DATA_BASE, pu8DataSec, (uint16)u32DataSize); fclose(fp); } free(pu8DataSec); } #endif nm_write_reg(0x108c, 0xdddd); }
/** * @fn spi_flash_pp * @brief Program data of size less than a page (256 bytes) at the SPI flash * @param[IN] u32Offset * Address to write to at the SPI flash * @param[IN] pu8Buf * Pointer to data buffer * @param[IN] u32Sz * Data size * @return Status of execution */ static sint8 spi_flash_pp(uint32 u32Offset, uint8 *pu8Buf, uint16 u16Sz) { sint8 ret = M2M_SUCCESS; uint8 tmp; spi_flash_write_enable(); /* use shared packet memory as temp mem */ ret += nm_write_block(HOST_SHARE_MEM_BASE, pu8Buf, u16Sz); ret += spi_flash_page_program(HOST_SHARE_MEM_BASE, u32Offset, u16Sz); ret += spi_flash_read_status_reg(&tmp); do { if(ret != M2M_SUCCESS) goto ERR; ret += spi_flash_read_status_reg(&tmp); }while(tmp & 0x01); ret += spi_flash_write_disable(); ERR: return ret; }
sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize, uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset) { sint8 ret = M2M_ERR_SEND; volatile tstrHifHdr strHif; strHif.u8Opcode = u8Opcode&(~NBIT7); strHif.u8Gid = u8Gid; strHif.u16Length = M2M_HIF_HDR_OFFSET; if(pu8DataBuf != NULL) { strHif.u16Length += u16DataOffset + u16DataSize; } else { strHif.u16Length += u16CtrlBufSize; } ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { volatile uint32 reg, dma_addr = 0; volatile uint16 cnt = 0; //#define OPTIMIZE_BUS /*please define in firmware also*/ #ifndef OPTIMIZE_BUS reg = 0UL; reg |= (uint32)u8Gid; reg |= ((uint32)u8Opcode<<8); reg |= ((uint32)strHif.u16Length<<16); ret = nm_write_reg(NMI_STATE_REG,reg); if(M2M_SUCCESS != ret) goto ERR1; reg = 0UL; reg |= NBIT1; ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg); if(M2M_SUCCESS != ret) goto ERR1; #else reg = 0UL; reg |= NBIT1; reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/ reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/ reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/ ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg); if(M2M_SUCCESS != ret) goto ERR1; #endif dma_addr = 0; for(cnt = 0; cnt < 1000; cnt ++) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)®); if(ret != M2M_SUCCESS) break; /* * If it takes too long to get a response, the slow down to * avoid back-to-back register read operations. */ if(cnt >= 500) { if(cnt < 501) { M2M_INFO("Slowing down...\n"); } nm_bsp_sleep(1); } if (!(reg & NBIT1)) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&dma_addr); if(ret != M2M_SUCCESS) { /*in case of read error clear the DMA address and return error*/ dma_addr = 0; goto ERR1; } /*in case of success break */ break; } } if (dma_addr != 0) { volatile uint32 u32CurrAddr; u32CurrAddr = dma_addr; strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length); ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET); if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += M2M_HIF_HDR_OFFSET; if(pu8CtrlBuf != NULL) { ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize); if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16CtrlBufSize; } if(pu8DataBuf != NULL) { u32CurrAddr += (u16DataOffset - u16CtrlBufSize); ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize); if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16DataSize; } reg = dma_addr << 2; reg |= NBIT1; ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg); if(M2M_SUCCESS != ret) goto ERR1; } else { ret = hif_chip_sleep(); M2M_DBG("Failed to alloc rx size %d\r",ret); ret = M2M_ERR_MEM_ALLOC; goto ERR2; } } else { M2M_ERR("(HIF)Fail to wakup the chip\n"); goto ERR2; } /*actual sleep ret = M2M_SUCCESS*/ ret = hif_chip_sleep(); return ret; ERR1: /*reset the count but no actual sleep as it already bus error*/ hif_chip_sleep_sc(); ERR2: /*logical error*/ 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; }
sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize, uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset) { sint8 ret = M2M_ERR_SEND; volatile tstrHifHdr strHif; strHif.u8Opcode = u8Opcode&(~NBIT7); strHif.u8Gid = u8Gid; strHif.u16Length = M2M_HIF_HDR_OFFSET; if(pu8DataBuf != NULL) { strHif.u16Length += u16DataOffset + u16DataSize; } else { strHif.u16Length += u16CtrlBufSize; } ret = hif_chip_wake(); if(ret == M2M_SUCCESS) { volatile uint32 reg, dma_addr = 0; volatile uint16 cnt = 0; reg = 0UL; reg |= (uint32)u8Gid; reg |= ((uint32)u8Opcode<<8); reg |= ((uint32)strHif.u16Length<<16); ret = nm_write_reg(NMI_STATE_REG,reg); if(M2M_SUCCESS != ret) goto ERR1; reg = 0; reg |= (1<<1); ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg); if(M2M_SUCCESS != ret) goto ERR1; dma_addr = 0; //nm_bsp_interrupt_ctrl(0); for(cnt = 0; cnt < 1000; cnt ++) { ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)®); if(ret != M2M_SUCCESS) break; if (!(reg & 0x2)) { ret = nm_read_reg_with_ret(0x150400,(uint32 *)&dma_addr); if(ret != M2M_SUCCESS) { /*in case of read error clear the dma address and return error*/ dma_addr = 0; } /*in case of success break */ break; } } //nm_bsp_interrupt_ctrl(1); if (dma_addr != 0) { volatile uint32 u32CurrAddr; u32CurrAddr = dma_addr; strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length); ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += M2M_HIF_HDR_OFFSET; if(pu8CtrlBuf != NULL) { ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16CtrlBufSize; } if(pu8DataBuf != NULL) { u32CurrAddr += (u16DataOffset - u16CtrlBufSize); ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize); #ifdef CONF_WINC_USE_I2C nm_bsp_sleep(1); #endif if(M2M_SUCCESS != ret) goto ERR1; u32CurrAddr += u16DataSize; } reg = dma_addr << 2; reg |= (1 << 1); ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg); if(M2M_SUCCESS != ret) goto ERR1; } else { M2M_DBG("Failed to alloc rx size\r"); ret = M2M_ERR_MEM_ALLOC; goto ERR1; } } else { M2M_ERR("(HIF)Fail to wakup the chip\n"); goto ERR1; } ret = hif_chip_sleep(); ERR1: return ret; }