Example #1
0
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;
}
Example #3
0
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 *)&reg);
			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 *)&reg);
			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;
}