www.pudn.com > iMx31_WCE600.rar > sboot.c
// // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. // If you did not accept the terms of the EULA, you are not authorized to use // this source code. For a copy of the EULA, please see the LICENSE.RTF on your // install media. // //------------------------------------------------------------------------------ // // Copyright (C) 2007, Freescale Semiconductor, Inc. All Rights Reserved. // THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS // AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT // //------------------------------------------------------------------------------ // // File: sboot.c // // Core routines for the Serial bootloader. // //----------------------------------------------------------------------------- #include#include #include //----------------------------------------------------------------------------- // External Functions //----------------------------------------------------------------------------- // External Variables extern BSP_ARGS *g_pBSPArgs; extern PCSP_PBC_REGS g_pPBC; extern PCSP_IOMUX_REGS g_pIOMUX; extern PCSP_CCM_REGS g_pCCM; extern BOOT_CFG g_BootCFG; extern BOOT_BINDIO_CONTEXT g_BinDIO; //----------------------------------------------------------------------------- // Global Variables static PCSP_UART_REG g_pUART; // serial packet header and trailer definitions static const UCHAR packetHeaderSig[] = { 'k', 'I', 'T', 'L' }; __declspec(align(4)) BYTE g_buffer[KITL_MTU]; BOOT_CFG *pBootArgs = &g_BootCFG; //----------------------------------------------------------------------------- // Defines #define DEF_BAUD_RATE 115200 // DEF_BAUD_RATE must be one of 115200, 57600, 38400, 19200, 9600 // Use the serial bootloader in conjunction with the serial kitl transport // Both the transport and the download service expect packets with the // same header format. Packets not of type DLREQ, DLPKT, or DLACK are // ignored by the serial bootloader. #define KITL_MAX_DEV_NAMELEN 16 #define KITL_MTU 1520 #define HEADER_SIG_BYTES sizeof(packetHeaderSig) #define KS_PKT_KITL 0xAA #define KS_PKT_DLREQ 0xBB #define KS_PKT_DLPKT 0xCC #define KS_PKT_DLACK 0xDD #define KS_PKT_JUMP 0xEE // serial port definitions #define UART_UCR2_CTS_ACTIVE 0x1000 #define UART_RX_FRAMING_ERR 0x1000 #define UART_RX_PARITY_ERR 0x400 #define UART_RX_OVERRUN 0x2000 #define UART_RX_ERRORS (UART_RX_FRAMING_ERR | UART_RX_PARITY_ERR | UART_RX_OVERRUN) #define TIMEOUT_RECV 5 // seconds //----------------------------------------------------------------------------- // Types // packet header #include typedef struct tagSERIAL_PACKET_HEADER { UCHAR headerSig[HEADER_SIG_BYTES]; UCHAR pktType; UCHAR Reserved; USHORT payloadSize; // not including this header UCHAR crcData; UCHAR crcHdr; } SERIAL_PACKET_HEADER, *PSERIAL_PACKET_HEADER; #include // packet payload typedef struct tagSERIAL_BOOT_REQUEST { UCHAR PlatformId[KITL_MAX_DEV_NAMELEN+1]; UCHAR DeviceName[KITL_MAX_DEV_NAMELEN+1]; USHORT reserved; } SERIAL_BOOT_REQUEST, *PSERIAL_BOOT_REQUEST; typedef struct tagSERIAL_BOOT_ACK { DWORD fJumping; } SERIAL_BOOT_ACK, *PSERIAL_BOOT_ACK; typedef struct tagSERIAL_JUMP_REQUST { DWORD dwKitlTransport; } SERIAL_JUMP_REQUEST, *PSERIAL_JUMP_REQUEST; typedef struct tagSERIAL_BLOCK_HEADER { DWORD uBlockNum; } SERIAL_BLOCK_HEADER, *PSERIAL_BLOCK_HEADER; //----------------------------------------------------------------------------- // Local Variables //------------------------------------------------------------------------------ // Local Functions // BOOL OEMSerialSendRaw(LPBYTE pbFrame, USHORT cbFrame); BOOL OEMSerialRecvRaw(LPBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite); BOOL RecvHeader(PSERIAL_PACKET_HEADER pHeader, BOOLEAN bWaitInfinite); BOOL RecvPacket(PSERIAL_PACKET_HEADER pHeader, PBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite); BOOL WaitForJump(VOID); BOOL WaitForBootAck(BOOL *pfJump); BOOL SerialSendBlockAck(DWORD uBlockNumber); BOOL SerialSendBootRequest(VOID); static BOOL SBOOTReadData (DWORD cbData, LPBYTE pbData); void ResetDefaultBootCFG(BOOT_CFG *pBootCFG); // OS launch function type typedef void (*PFN_LAUNCH)(); //------------------------------------------------------------------------------ // // Function: OEMBootInit // // Parameters: // None. // // Returns: // None. //------------------------------------------------------------------------------ void OEMBootInit (void) { KITLOutputDebugString("Microsoft Windows CE Serial Bootloader %d.%d for MX32 ADS (%s %s)\r\n", SBOOT_VERSION_MAJOR, SBOOT_VERSION_MINOR, __DATE__, __TIME__); return; } //------------------------------------------------------------------------------ // // Function: OEMGetMagicNumber // // Parameters: // None. // // Returns: // Magic number of SBOOT version. //------------------------------------------------------------------------------ UINT32 OEMGetMagicNumber() { return SBOOT_CFG_MAGIC_NUMBER; } //------------------------------------------------------------------------------ // // Function: GetPreDownloadInfo // // Parameters: // None. // // Returns: // TRUE for Download/FALSE for jump to resident OS image //------------------------------------------------------------------------------ BOOL GetPreDownloadInfo (PBOOT_CFG p_bootCfg) { BOOL fGotJump = FALSE; BOOL bParityEnable = TRUE; SERIAL_INFO serInfo; DWORD dwParity = p_bootCfg->Parity; switch (p_bootCfg->Channel) { case 1: p_bootCfg->dwSerPhysAddr = CSP_BASE_REG_PA_UART1; break; case 2: p_bootCfg->dwSerPhysAddr = CSP_BASE_REG_PA_UART2; break; case 3: p_bootCfg->dwSerPhysAddr = CSP_BASE_REG_PA_UART3; break; case 4: p_bootCfg->dwSerPhysAddr = CSP_BASE_REG_PA_UART4; break; case 5: p_bootCfg->dwSerPhysAddr = CSP_BASE_REG_PA_UART5; break; default: p_bootCfg->dwSerPhysAddr = DEFAULT_SBOOT_BASE_REG; break; } g_pUART = (PCSP_UART_REG) OALPAtoUA(p_bootCfg->dwSerPhysAddr); if (g_pUART == NULL) { return FALSE; } if (p_bootCfg->Parity == SBOOT_PARITY_NONE) { bParityEnable = FALSE; dwParity = SBOOT_PARITY_EVEN; } serInfo.baudRate = p_bootCfg->BaudRate; serInfo.uartBaseAddr = p_bootCfg->dwSerPhysAddr; serInfo.dataBits = p_bootCfg->DataBits; serInfo.parity = dwParity; serInfo.bParityEnable = bParityEnable; serInfo.flowControl = p_bootCfg->FlowCtrl; serInfo.stopBits = p_bootCfg->StopBit; OALSerialInit(&serInfo); // send boot requests indefinitely do { EdbgOutputDebugString("Sending sboot request...\r\n"); if(!SerialSendBootRequest()) { EdbgOutputDebugString("Failed to send sboot request\r\n"); return BL_ERROR; } } while(!WaitForBootAck(&fGotJump)); // ack block zero to start the download SerialSendBlockAck(0); EdbgOutputDebugString("Received sboot request ack... starting download\r\n"); return fGotJump ? BL_JUMP : BL_DOWNLOAD; } //------------------------------------------------------------------------------ // // Function: GetLaunchInfo // // Parameters: // None. // // Returns: // None. //------------------------------------------------------------------------------ void GetLaunchInfo (void) { // wait for jump packet indefinitely if(WaitForJump() == FALSE) { EdbgOutputDebugString("Failed to wait for jump message\r\n"); } return; } //----------------------------------------------------------------------------- // // Function: OEMReadData // // This function reads data from the transport during the download process. // It is called by the BLCOMMON framework. // // Parameters: // cbData // [in] Amount of data, in bytes, to read. // // pbData // [out] Pointer to read buffer. // // Returns: // TRUE for success/FALSE for failure. // //----------------------------------------------------------------------------- BOOL OEMReadData(DWORD cbData, LPBYTE pbData) { BOOL bRet = TRUE; // TODO: increment bytes read to track download progress. // Save read data size and location. It is used in workaround // for download BIN DIO images larger than RAM. g_BinDIO.readSize = cbData; g_BinDIO.pReadBuffer = pbData; bRet = SBOOTReadData(cbData, pbData); return bRet; } //----------------------------------------------------------------------------- // // Function: SBOOTReadData // // This function reads data from the serial transport during the download. // // Parameters: // cbData // [in] Amount of data, in bytes, to read. // // pbData // [out] Pointer to read buffer. // // Returns: // TRUE for success/FALSE for failure. //----------------------------------------------------------------------------- static BOOL SBOOTReadData (DWORD cbData, LPBYTE pbData) { static DWORD dwBlockNumber = 0; static USHORT cbDataBuffer = 0; static BYTE dataBuffer[KITL_MTU] = {0}; // the first DWORD in the local buffer is the block header which contains // the sequence number of the block received static PSERIAL_BLOCK_HEADER pBlockHeader = (PSERIAL_BLOCK_HEADER)dataBuffer; static PBYTE pBlock = dataBuffer + sizeof(PSERIAL_BLOCK_HEADER); SERIAL_PACKET_HEADER header; USHORT cbPacket; LPBYTE pOutBuffer = pbData; while(cbData) { // if there is no data in the local buffer, read some // while(0 == cbDataBuffer) { // read from port cbPacket = sizeof(dataBuffer); if(RecvPacket(&header, dataBuffer, &cbPacket, TRUE)) { // ignore non-download packet types if(KS_PKT_DLPKT == header.pktType) { // make sure we received the correct block in the sequence if(dwBlockNumber == pBlockHeader->uBlockNum) { cbDataBuffer = header.payloadSize - sizeof(SERIAL_BLOCK_HEADER); dwBlockNumber++; } else { EdbgOutputDebugString("Received out of sequence block %u\r\n", pBlockHeader->uBlockNum); EdbgOutputDebugString("Expected block %u\r\n", dwBlockNumber); } // ack, or re-ack the sender if(dwBlockNumber > 0) { // block number has already been incremented when appropriate SerialSendBlockAck(dwBlockNumber - 1); } } } } // copy from local buffer into output buffer // // if there are more than the requested bytes, copy and shift // the local data buffer if(cbDataBuffer > cbData) { // copy requested bytes from local buffer into output buffer memcpy(pOutBuffer, pBlock, cbData); cbDataBuffer = (USHORT)(cbDataBuffer - cbData); // shift the local buffer accordingly because not all data was used memmove(pBlock, pBlock + cbData, cbDataBuffer); cbData = 0; } else // cbDataBuffer <= cbData { // copy all bytes in local buffer to output buffer memcpy(pOutBuffer, pBlock, cbDataBuffer); cbData -= cbDataBuffer; pOutBuffer += cbDataBuffer; cbDataBuffer = 0; } } return TRUE; } //----------------------------------------------------------------------------- // // Function: CalcChksum // // This function calculates the checksum of the serial data. // // Parameters: // pBuf // [in] Data Buffer. // // len // [in] Length of the buffer. // // Returns: // Checksum calculated //----------------------------------------------------------------------------- UCHAR CalcChksum(PUCHAR pBuf, USHORT len) { USHORT s = 0; UCHAR csum = 0; for(s = 0; s < len; s++) csum = (UCHAR)(csum + (*(pBuf + s))); return csum; } //----------------------------------------------------------------------------- // // Function: SerialSendBootRequest // // This function sends Boot requests through serial interface. // // Parameters: // None // // Returns: // TRUE for success/FALSE for failure. //----------------------------------------------------------------------------- BOOL SerialSendBootRequest(VOID) { BYTE buffer[sizeof(SERIAL_PACKET_HEADER) + sizeof(SERIAL_BOOT_REQUEST)] = {0}; PSERIAL_PACKET_HEADER pHeader = (PSERIAL_PACKET_HEADER)buffer; PSERIAL_BOOT_REQUEST pBootReq = (PSERIAL_BOOT_REQUEST)(buffer + sizeof(SERIAL_PACKET_HEADER)); // create boot request PREFAST_SUPPRESS(5425, "Suppressed since it requires coredll.lib which increases the image drastically"); strcpy((CHAR *)pBootReq->PlatformId, (const CHAR *)g_pBSPArgs->deviceId); // create header memcpy(pHeader->headerSig, packetHeaderSig, HEADER_SIG_BYTES); pHeader->pktType = KS_PKT_DLREQ; pHeader->payloadSize = sizeof(SERIAL_BOOT_REQUEST); pHeader->crcData = CalcChksum((PBYTE)pBootReq, sizeof(SERIAL_BOOT_REQUEST)); pHeader->crcHdr = CalcChksum((PBYTE)pHeader, sizeof(SERIAL_PACKET_HEADER) - sizeof(pHeader->crcHdr)); INSREG32BF(&g_pUART->UCR2, UART_UCR2_IRTS, UART_UCR2_IRTS_IGNORERTS); OEMSerialSendRaw(buffer, sizeof(SERIAL_PACKET_HEADER) + sizeof(SERIAL_BOOT_REQUEST)); OUTREG32(&g_pUART->UCR2, INREG32(&g_pUART->UCR2)&~CSP_BITFMASK(UART_UCR2_IRTS)); 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 }