?? sboot.c
字號:
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 + -