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;
}
Exemple #2
0
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 *)&reg);
		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;
}
Exemple #5
0
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;
}
Exemple #6
0
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 *)&reg);
		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 *)&reg);
		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;
}