⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sboot.c

📁 i.Mx31 bootloader(for WinCE6.0)
💻 C
📖 第 1 页 / 共 2 页
字号:
    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function:  SerialSendBlockAck
//
//  This function sends Boot requests through serial interface. 
//
//  Parameters:
//      uBlockNumber
//           [in] Serial Block data
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL SerialSendBlockAck(DWORD uBlockNumber)
{
    BYTE buffer[sizeof(SERIAL_PACKET_HEADER) + sizeof(SERIAL_BLOCK_HEADER)];
    PSERIAL_PACKET_HEADER pHeader = (PSERIAL_PACKET_HEADER)buffer;
    PSERIAL_BLOCK_HEADER pBlockAck = (PSERIAL_BLOCK_HEADER)(buffer + sizeof(SERIAL_PACKET_HEADER));

    // create block ack
    pBlockAck->uBlockNum = uBlockNumber;

    // create header
    memcpy(pHeader->headerSig, packetHeaderSig, HEADER_SIG_BYTES);
    pHeader->pktType = KS_PKT_DLACK;
    pHeader->payloadSize = sizeof(SERIAL_BLOCK_HEADER);
    pHeader->crcData = CalcChksum((PBYTE)pBlockAck, sizeof(SERIAL_BLOCK_HEADER));
    pHeader->crcHdr = CalcChksum((PBYTE)pHeader,
        sizeof(SERIAL_PACKET_HEADER) - sizeof(pHeader->crcHdr));

    OEMSerialSendRaw(buffer, sizeof(SERIAL_PACKET_HEADER) + sizeof(SERIAL_BLOCK_HEADER));

    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function:  WaitForBootAck
//
//  This function will fail if a boot ack is not received in a timely manner
//  so that another boot request can be sent
//
//  Parameters:
//      pfJump
//           [out] TRUE if recvd boot ack
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL WaitForBootAck(BOOL *pfJump)
{
    BOOL fRet = FALSE;
    USHORT cbBuffer = KITL_MTU;
    SERIAL_PACKET_HEADER header = {0};
    PSERIAL_BOOT_ACK pBootAck = (PSERIAL_BOOT_ACK)g_buffer;

    EdbgOutputDebugString("Waiting for sboot ack...\r\n");
    if(RecvPacket(&header, g_buffer, &cbBuffer, FALSE))
    {
        // header checksum already verified
        if(KS_PKT_DLACK == header.pktType && 
            sizeof(SERIAL_BOOT_ACK) == header.payloadSize)
        {
            EdbgOutputDebugString("Received sboot ack\r\n");
            *pfJump = pBootAck->fJumping;
            fRet = TRUE;
        }
    }

    return fRet;
}

//-----------------------------------------------------------------------------
//
//  Function:  WaitForBootAck
//
//  This function waits indefinitely for jump command
//
//  Parameters:
//      None
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL WaitForJump(VOID)
{
    USHORT cbBuffer = KITL_MTU;
    SERIAL_PACKET_HEADER header = {0};
    PSERIAL_JUMP_REQUEST pJumpReq = (PSERIAL_JUMP_REQUEST)g_buffer;

    // wait indefinitely for a jump request
    for (;;)
    {
        if(RecvPacket(&header, g_buffer, &cbBuffer, TRUE))
        {
            // header & checksum already verified
            if(KS_PKT_JUMP == header.pktType && 
                sizeof(SERIAL_JUMP_REQUEST) == header.payloadSize)
            { 
				if (pJumpReq->dwKitlTransport == KTS_SERIAL)
					g_pBSPArgs->kitl.devLoc.PhysicalLoc = (PVOID)(BSP_BASE_REG_PA_SERIALKITL);

				if (pJumpReq->dwKitlTransport & KTS_PASSIVE_MODE)
					g_pBSPArgs->kitl.flags = OAL_KITL_FLAGS_PASSIVE;

                SerialSendBlockAck(0);

				if (pJumpReq->dwKitlTransport == KTS_SERIAL)
				{
					CHAR cLoop = 5;
					// Keep sending ACK till Platform Builder stops sending JUMP packets
					// Retry for a maximum of 5 times
					do 
					{
						if ( !((RecvPacket(&header, g_buffer, &cbBuffer, TRUE)) &&
							(KS_PKT_JUMP == header.pktType)) )
						{
							cLoop = 0;
						}
						SerialSendBlockAck(0);
						cLoop--;
					} while (cLoop > 0);
				}
				else if (pJumpReq->dwKitlTransport == KTS_ETHER)
				{
				        UINT32 EthDevice = InitSpecifiedEthDevice(&g_pBSPArgs->kitl,  ETH_DEVICE_CS8900A);
				        if (EthDevice == -1)
				        {
				            // No device was found ... 
				            //
				            KITLOutputDebugString("ERROR: Failed to detect and initialize Ethernet controller for KITL.\r\n");
				            return FALSE;
				        }
						else
						{
							// Make sure MAC address has been programmed.
							//
							if (!g_pBSPArgs->kitl.mac[0] && !g_pBSPArgs->kitl.mac[1] && !g_pBSPArgs->kitl.mac[2])
							{
								KITLOutputDebugString("ERROR: Invalid Ethernet address read from Ethernet controller.\n");
								return(FALSE);
							}

							KITLOutputDebugString("INFO: MAC address: %x-%x-%x-%x-%x-%x\r\n",
								g_pBSPArgs->kitl.mac[0] & 0x00FF, g_pBSPArgs->kitl.mac[0] >> 8,
								g_pBSPArgs->kitl.mac[1] & 0x00FF, g_pBSPArgs->kitl.mac[1] >> 8,
								g_pBSPArgs->kitl.mac[2] & 0x00FF, g_pBSPArgs->kitl.mac[2] >> 8);
						}
				}
                return TRUE;
            }
        }
    }

#if 0 // Remove-W4: Warning C4702 workaround
    // never reached
    return FALSE;    
#endif
}

//-----------------------------------------------------------------------------
//
//  Function:  RecvPacket
//
//  This function receives serial packet
//
//  Parameters:
//      pHeader
//          [in] Serial packet header
//
//      pbFrame
//          [in] Serial frame data
//
//      pcbFrame
//          [in] Length of frame
//
//      bWaitInfinite
//          [in] Time to wait in secs
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL RecvPacket(PSERIAL_PACKET_HEADER pHeader, PBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite)
{
    // receive header
    if(!RecvHeader(pHeader, bWaitInfinite))
    {
        EdbgOutputDebugString("failed to receive header\r\n");
        return FALSE;
    }

    // verify packet checksum
    if(pHeader->crcHdr != CalcChksum((PBYTE)pHeader, 
        sizeof(SERIAL_PACKET_HEADER) - sizeof(pHeader->crcHdr)))
    {
        EdbgOutputDebugString("header checksum failure\r\n");
        return FALSE;
    }

    // make sure sufficient buffer is provided
    if(*pcbFrame < pHeader->payloadSize)
    {
        EdbgOutputDebugString("insufficient buffer size; ignoring packet\r\n");
        return FALSE;
    }

    // receive data
    *pcbFrame = pHeader->payloadSize;
    if(!OEMSerialRecvRaw(pbFrame, pcbFrame, bWaitInfinite))
    {
        //EdbgOutputDebugString("failed to read packet data\r\n");
        return FALSE;
    }

    // verify data checksum
    if(pHeader->crcData != CalcChksum(pbFrame, *pcbFrame))
    {
        EdbgOutputDebugString("data checksum failure\r\n");
        return FALSE;
    }

    // verify packet type -- don't return any packet that is not
    // a type the bootloader expects to receive
    if(KS_PKT_DLPKT != pHeader->pktType &&
       KS_PKT_DLACK != pHeader->pktType &&
       KS_PKT_JUMP != pHeader->pktType)
    {
        EdbgOutputDebugString("received non-download packet type %x\r\n", pHeader->pktType);
        return FALSE;
    }

    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function:  RecvHeader
//
//  This function receives serial header packet
//
//  Parameters:
//      pHeader
//          [in] Serial packet header
//
//      bWaitInfinite
//          [in] Time to wait in secs
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL RecvHeader(PSERIAL_PACKET_HEADER pHeader, BOOLEAN bWaitInfinite)
{
    USHORT cbRead;
    UINT i = 0;
    cbRead = sizeof(UCHAR);
    // read the header bytes
    while(i < HEADER_SIG_BYTES)
    {
        if(!OEMSerialRecvRaw((PBYTE)&(pHeader->headerSig[i]), &cbRead, bWaitInfinite) || sizeof(UCHAR) != cbRead)
        {
            EdbgOutputDebugString("failed to receive header signature\r\n");
            return FALSE;
        }

        if(pHeader->headerSig[i] == packetHeaderSig[i])
        {
            i++;
        }

        else
        {
            i = 0;
        }
    }

    // read the remaining header
    cbRead = sizeof(SERIAL_PACKET_HEADER) - HEADER_SIG_BYTES;
    if(!OEMSerialRecvRaw((PUCHAR)pHeader + HEADER_SIG_BYTES, &cbRead, bWaitInfinite) ||
        sizeof(SERIAL_PACKET_HEADER) - HEADER_SIG_BYTES != cbRead)
    {
        EdbgOutputDebugString("failed to receive header data\r\n");
        return FALSE;
    }
    
    // verify the header checksum
    if(pHeader->crcHdr != CalcChksum((PUCHAR)pHeader, 
        sizeof(SERIAL_PACKET_HEADER) - sizeof(pHeader->crcHdr)))
    {
        EdbgOutputDebugString("header checksum fail\r\n");
        return FALSE;
    }

    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function:  OEMSerialRecvRaw
//
//  This is platform specific function to receive data
//
//  Parameters:
//      pbFrame
//          [in] Serial frame data
//
//      pcbFrame
//          [in] Length of frame
//
//      bWaitInfinite
//          [in] Time to wait in secs
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL OEMSerialRecvRaw(LPBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite)
{
	USHORT ct = 0;
    DWORD tStart = 0;
#if 0 // Remove-W4: Warning C4189 workaround
    UCHAR uStatus = 0;
#endif
	UINT32 urxd;
	
	INSREG32BF(&g_pUART->UCR2, UART_UCR2_IRTS, UART_UCR2_IRTS_IGNORERTS);	
	INSREG32BF(&g_pUART->UCR2, UART_UCR2_CTS, UART_UCR2_CTS_LOW);
    
	for(ct = 0; ct < *pcbFrame; ct++)
    {
		if (!bWaitInfinite)
		{
			tStart = OEMEthGetSecs();
		}

		while (!(INREG32(&g_pUART->USR2) & CSP_BITFMASK(UART_USR2_RDR)))
        {
            if(!bWaitInfinite && (OEMEthGetSecs() - tStart > TIMEOUT_RECV))
            {
                *pcbFrame = 0;
				OUTREG32(&g_pUART->UCR2, 
					INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS));
				OUTREG32(&g_pUART->UCR2, 
						INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_IRTS));
				
                return FALSE;
            }            
        }

		// read char from FIFO
        urxd = INREG32(&g_pUART->URXD);

        // check and clear comm errors
        // If error detected in current character
		if (urxd & UART_RX_ERRORS)
        {
            // clear the queue
            EdbgOutputDebugString("Comm errors have occurred; status = 0x%x\r\n", urxd);
			OUTREG32(&g_pUART->UCR2, 
					INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS));
			OUTREG32(&g_pUART->UCR2, 
						INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_IRTS));
			return FALSE;
        }

        *(pbFrame + ct) = (BYTE)(urxd & 0xFF);
    }

	OUTREG32(&g_pUART->UCR2, 
            INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_CTS));
	OUTREG32(&g_pUART->UCR2, 
                INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_IRTS));
	
  return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function:  OEMSerialSendRaw
//
//  This is platform specific function to send data
//
//  Parameters:
//      pbFrame
//          [in] Serial frame data
//
//      pcbFrame
//          [in] Length of frame
//
//  Returns:
//      TRUE for success/FALSE for failure.
//-----------------------------------------------------------------------------
BOOL OEMSerialSendRaw(LPBYTE pbFrame, USHORT cbFrame)
{
	UINT ct;

    // block until send is complete; no timeout
    for(ct = 0; ct < cbFrame; ct++)
    {            
        // check that send transmitter holding register is not full
        while(INREG32(&g_pUART->UTS) & CSP_BITFMASK(UART_UTS_TXFULL));

        // write character to port
        OUTREG32(&g_pUART->UTXD, (UCHAR)*(pbFrame+ct));
    }
    return TRUE;
}


//------------------------------------------------------------------------------
//
//  Function:  ResetDefaultBootCFG
//
//  Resets the debug bootloader configuration information (menu settings, etc.).
//
//  Parameters:
//      BootCfg 
//          [out] Points to bootloader configuration that will be filled with
//          default data. 
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
void ResetDefaultBootCFG(BOOT_CFG *pBootCFG)
{
#ifdef DEBUG // Remove-W4: Warning C4189 workaround
    BOOT_CFG BootCfg = {0};
#endif

    KITLOutputDebugString("\r\nResetting factory default configuration...\r\n");

    pBootCFG->autoDownloadImage			= BOOT_CFG_AUTODOWNLOAD_NONE;
    pBootCFG->dwLaunchAddr				= (DWORD)OALPAtoCA(IMAGE_BOOT_NKIMAGE_RAM_PA_START);
    pBootCFG->dwPhysStart				= 0;
    pBootCFG->dwPhysLen					= 0;
    pBootCFG->mac[0]					= 0x0000;
    pBootCFG->mac[1]					= 0x0000;
    pBootCFG->mac[2]					= 0x0000; 
    pBootCFG->ConfigMagicNumber			= SBOOT_CFG_MAGIC_NUMBER;
	pBootCFG->numBootMe					= 50;
    pBootCFG->delay						= 3;

	pBootCFG->Channel			= DEFAULT_SBOOT_CHANNEL;
	pBootCFG->dwSerPhysAddr	= DEFAULT_SBOOT_BASE_REG;
    pBootCFG->BaudRate			= DEFAULT_SBOOT_BAUDRATE; 
    pBootCFG->DataBits			= SBOOT_DATABITS_8;
    pBootCFG->Parity           = SBOOT_PARITY_NONE;
	pBootCFG->StopBit			= SBOOT_STOPBITS_1;
	pBootCFG->FlowCtrl			= SBOOT_FLOWCTRL_OFF;
	
    // save it back to flash
    if (!FlashStoreBootCFG((BYTE*) pBootCFG, sizeof(BOOT_CFG))) 
    {
        KITLOutputDebugString("ERROR: ResetDefaultBootCFG: failed to store configuration to flash.\r\n");
    }
#ifdef DEBUG
    else
    {
        KITLOutputDebugString("INFO: ResetDefaultBootCFG: factory default configuration saved to flash.\r\n");

        // DEBUG
        // read it back to verify
        if (!FlashLoadBootCFG((BYTE*) &BootCfg, sizeof(BOOT_CFG))) 
        {
            KITLOutputDebugString("WARNING: ResetDefaultBootCFG: failed to load configuration for double check.\r\n");
        }
        else
        {
            if (0 != memcmp((const void *)&BootCfg, (const void*)pBootCFG, sizeof(BOOT_CFG)))
            {
                KITLOutputDebugString("WARNING: ResetDefaultBootCFG: saved and retrieved data not equal.\r\n");
            }
            else
            {
                KITLOutputDebugString("INFO: ResetDefaultBootCFG: factory default configuration verified in flash.\r\n");
            }
        }
        // END DEBUG
    }
#endif    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -