main.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 881 行 · 第 1/3 页

C
881
字号
    //
    // Get pointer to Boot Args...
    //
    pBootArgs = (BOOT_ARGS *) ((ULONG)(*(PBYTE *)BOOT_ARG_PTR_LOCATION_NP));
    EdbgOutputDebugString("***************************\r\n");
    EdbgOutputDebugString("***************************\r\n");
    EdbgOutputDebugString("Boot Args @ 0x%x\r\n", pBootArgs);
    EdbgOutputDebugString("Boot Args @ 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", (DWORD)pBootArgs->vesaMode,(DWORD)pBootArgs->cxDisplayScreen,
		(DWORD)pBootArgs->cyDisplayScreen,(DWORD)pBootArgs->bppScreen, pBootArgs->pvFlatFrameBuffer);


    if (BOOTARG_SIG != pBootArgs->dwEBootFlag) {
        pBootArgs->dwEBootFlag = BOOTARG_SIG;
        dwBootFlags = EDBG_BOOTFLAG_FORCE_DOWNLOAD;
    }
    pBootArgs->dwEBootAddr = (DWORD)EbootMain;
    pBootArgs->ucLoaderFlags = 0;

    //
    // What PCI hardware is available?
    //
    PrintPCIConfig();

    if (pBootArgs->dwEdbgBaseAddr == 0) {
        //
        // The user can specify a ZERO base address and we'll try to find 
        // the PCI net card that matched the IRQ (set by the BIOS)
        //
        pBootArgs->dwEdbgBaseAddr = FindPCINetCard(pBootArgs->ucEdbgIRQ);
        if (pBootArgs->dwEdbgBaseAddr == 0) {
            EdbgOutputDebugString("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
            EdbgOutputDebugString("---------------------------------------------\r\n");
            EdbgOutputDebugString(" Failed to locate the Ethernet board!\r\n");
            EdbgOutputDebugString(" A base I/O address of ZERO was specified, but\r\n");
            EdbgOutputDebugString(" no PCI Ethernet Card was found at IRQ %d.\r\n", pBootArgs->ucEdbgIRQ);
            EdbgOutputDebugString("---------------------------------------------\r\n");
            EdbgOutputDebugString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n");
            SpinForever();
        }
    }
    
    // Some parameters included in boot args for future use, make sure these aren't set
    switch (pBootArgs->ucEdbgAdapterType) {


#ifdef NOTDEF        
        case EDBG_ADAPTER_NE2000:
            pfnEDbgInit           = NE2000Init;
            pfnEDbgEnableInts     = NE2000EnableInts;     
            pfnEDbgDisableInts    = NE2000DisableInts;    
            pfnEDbgGetPendingInts = NE2000GetPendingInts; 
            pfnEDbgGetFrame       = NE2000GetFrame;       
            pfnEDbgSendFrame      = NE2000SendFrame;      
            pfnEDbgReadEEPROM     = NE2000ReadEEPROM;     
            pfnEDbgWriteEEPROM    = NE2000WriteEEPROM;    
            break;
        
#else
        //
        //  FIX THIS - FIX THIS - FIX THIS
        //  loadcepc does not take anything else except EDBG_ADAPTER_NE2000 ???
        //  
        case 0:
        case EDBG_ADAPTER_NE2000:
            //  
            //  Well, since we are cheating with NE2000, let the HAL know that
            //  it is actually ADAPTER_OEM.
            //  As and when the RTL8139 becomes global, then we should define 
            //  EDBG_ADAPTER_8139..
            //
            pBootArgs->ucEdbgAdapterType = EDBG_ADAPTER_OEM;

            EdbgOutputDebugString("Using RealTek Native Ether\r\n");

            if (!RTL8139InitDMABuffer(
                    0x00200000,
                    0x20000))
            {
                EdbgOutputDebugString("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
                EdbgOutputDebugString("---------------------------------------------\r\n");
                EdbgOutputDebugString(" Failed RTL8139InitDMABuffer() \r\n");
                EdbgOutputDebugString(" DMA buffer size must be too small.\r\n");
                EdbgOutputDebugString("---------------------------------------------\r\n");
                EdbgOutputDebugString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n");
                SpinForever();
            }                   
            pfnEDbgInit           = RTL8139Init;
            pfnEDbgEnableInts     = RTL8139EnableInts;     
            pfnEDbgDisableInts    = RTL8139DisableInts;    
            pfnEDbgGetPendingInts = RTL8139GetPendingInts; 
            pfnEDbgGetFrame       = RTL8139GetFrame;       
            pfnEDbgSendFrame      = RTL8139SendFrame;      
            pfnEDbgReadEEPROM     = RTL8139ReadEEPROM;     
            pfnEDbgWriteEEPROM    = RTL8139WriteEEPROM;             
            break;
#endif

        default:
        EdbgOutputDebugString("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
        EdbgOutputDebugString("---------------------------------------------\r\n");
        EdbgOutputDebugString(" Unsupported Ethernet Adapter %u\r\n", pBootArgs->ucEdbgAdapterType);
        EdbgOutputDebugString(" Please use :\r\n");
        EdbgOutputDebugString("     %2d : SMC9000\r\n", EDBG_ADAPTER_SMC9000);
        EdbgOutputDebugString("     %2d : NE2000 (or compatible)\r\n", EDBG_ADAPTER_NE2000);
        EdbgOutputDebugString("---------------------------------------------\r\n");
        EdbgOutputDebugString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n");
        SpinForever();
    }
    
    if (!pfnEDbgInit( (BYTE *) pBootArgs->dwEdbgBaseAddr, 1, MyAddr.wMAC)) {
        EdbgOutputDebugString("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n");
        EdbgOutputDebugString("---------------------------------------------\r\n");
        EdbgOutputDebugString(" Failed to initialize Ethernet board!\r\n");
        EdbgOutputDebugString(" Please check that the Ethernet card is\r\n");
        EdbgOutputDebugString(" properly installed and configured.\r\n");
        EdbgOutputDebugString("---------------------------------------------\r\n");
        EdbgOutputDebugString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n");
        SpinForever();
    }
    

    EdbgOutputDebugString( "Returned MAC Address:%B:%B:%B:%B:%B:%B\r\n",
                           MyAddr.wMAC[0] & 0x00FF, MyAddr.wMAC[0] >> 8,
                           MyAddr.wMAC[1] & 0x00FF, MyAddr.wMAC[1] >> 8,
                           MyAddr.wMAC[2] & 0x00FF, MyAddr.wMAC[2] >> 8);
        
    // Create device name based on Ethernet address
    CreateDeviceName(&MyAddr, szDeviceName);
    EdbgOutputDebugString("Using device name: %s\n", szDeviceName);
    

    // IP address may have been passed in on loadcepc cmd line
    if (pBootArgs->EdbgAddr.dwIP != 0) {
        EdbgOutputDebugString("Using IP address passed in from command line: %X\r\n",pBootArgs->EdbgAddr.dwIP);
        MyAddr.dwIP = pBootArgs->EdbgAddr.dwIP;
        fGotIP = TRUE;  // Skip DHCP
        EdbgFlags |= EDBG_FLAGS_STATIC_IP;
        dwIPState = IPSTATE_GOTIP;
    }
    else
        fGotIP = FALSE; // Get IP addr from DHCP

    // Save our address in boot args area
    memcpy(&pBootArgs->EdbgAddr,&MyAddr,sizeof(MyAddr));        

    // Set up TFTP server.  Note that internally, we store port numbers in network byte order.
    EbootInitTFtp( htons(EDBG_DOWNLOAD_PORT), htons(EDBG_DOWNLOAD_PORT));
    EbootInitTFtpd();
    if (EbootTFtpdServerRegister( EDBG_DOWNLOAD_FILENAME, EthDown ))
        EdbgOutputDebugString( "Server Registration Failed\r\n" );

    // Initialize DHCP, and send out first request
    if (!fGotIP) {
        if (EbootInitDHCP( &MyAddr ))
            EdbgOutputDebugString( "Error On InitDHCP() Call\r\n" );

        EdbgOutputDebugString( "You have 10 seconds to prove that you exist (via net or serial input)...\r\n" );
        EdbgOutputDebugString ( "Wait for DHCP, enter new IP address, or CR to use existing IP: ");
    }

    fGotJumpimg = FALSE;
    fDownloading = FALSE;
    memset(&EshellHostAddr,0,sizeof(EDBG_ADDR));
    BootmeCnt = 0;
    
    dwStartTime = OEMEthGetSecs();

    // Loop until we have an IP address and eshell tells us which services are
    // configured for Ethernet
    while (!fGotJumpimg) {
        USHORT wLen, wDestPort, wSrcPort, wUDPDataLen, *pwUDPData;

        // Once we get our IP address, periodically send BOOTME commands to eshell.
        switch (dwIPState) {
        case IPSTATE_NONE:
            // We haven't gotten an IP address yet.  Call into DHCP to see if we
            // need to retransmit request, and poll serial port for user input.
            EbootDHCPRetransmit(&MyAddr,NULL,NULL);
            if (EbootReadSerialIP(&MyAddr, &dwSubnetMask)) {
                fGotIP = TRUE;
                dwIPState = IPSTATE_GOTIP;
                EdbgFlags |= EDBG_FLAGS_STATIC_IP;
                DHCPLeaseTime = DEFAULT_DHCP_LEASE;
            }
            break;

        case IPSTATE_GOTIP:
            // Send a gratuitous ARP (an ARP of our new IP address) to verify that no other
            // station is using our IP address.
            if (!EbootGratuitousARP(&MyAddr, FrameBuffer)) {
                dwIPState = IPSTATE_ARP;
                dwNextBootme = OEMEthGetSecs(); // use dwNextBootme for ARP timeout 
            } else {
                EdbgOutputDebugString("EbootGratuitousARP failed\r\n");
            }
            break;
        
        case IPSTATE_ARP:
            if ((OEMEthGetSecs() - dwNextBootme) >= ARP_RESPONSE_WAIT) {
                EdbgOutputDebugString("No ARP response in %d seconds, assuming ownership of %s\r\n",
                                      ARP_RESPONSE_WAIT, inet_ntoa(MyAddr.dwIP));
                dwIPState = IPSTATE_ARPED;
                dwNextBootme = 0;
            }
            break;

        case IPSTATE_ARPED:
            if ((BootmeCnt < MAX_BOOTME_CNT) &&
                ((BootmeCnt == 0) || (OEMEthGetSecs() >= dwNextBootme))) {
                EbootSendBootme(&MyAddr, EBOOT_VERSION_MAJOR, 
                                EBOOT_VERSION_MINOR, PLATFORM_STRING, 
                                szDeviceName,  EDBG_CPU_i486, dwBootFlags);
                BootmeCnt++;
                dwNextBootme = OEMEthGetSecs() + BOOTME_INTERVAL;
            }
            break;

        case IPSTATE_RETRY:
            EbootInitDHCP(&MyAddr);
            dwIPState = IPSTATE_NONE;
            break;
        }   // switch (dwIPState)
            
        // Get a frame and pass it to the appropriate handler routine
        wLen = sizeof(FrameBuffer);
        if (pfnEDbgGetFrame(FrameBuffer, &wLen)) {
            // Ethernet frame type is in 7th word of buffer
            USHORT wFrameType = *(USHORT *)(FrameBuffer + 6*sizeof(USHORT));

            switch (ntohs(wFrameType)) {
                case 0x0806:
                    if (EbootProcessARP(&MyAddr,FrameBuffer) == PROCESS_ARP_RESPONSE) {
                        switch (dwIPState) {
                        // Someone has responded to our gratuitous ARP request so they have our IP address.
                        // We need to retry the DHCP request. 
                        case IPSTATE_ARP:
                        case IPSTATE_GOTIP:
                            DHCPRetry++;
                            if (DHCPRetry > MAX_DHCP_RETRY) {
                                EdbgOutputDebugString( "Some other station has IP Address: %s !!! Aborting.\r\n", inet_ntoa(MyAddr.dwIP));
                                SpinForever();
                            }
                
                            EdbgOutputDebugString( "Some other station has IP Address: %s !!! Retrying.\r\n", inet_ntoa(MyAddr.dwIP));
                            dwIPState = IPSTATE_RETRY;
                            break;
                        }
                    }
                    break;

                case 0x0800:
                    if (!EbootCheckUDP(&MyAddr, FrameBuffer, &wDestPort, &wSrcPort, &pwUDPData, &wUDPDataLen)) {
                        switch (dwIPState) {
                        case IPSTATE_NONE:
                            if ((wDestPort == DHCP_CLIENT_PORT) && (wSrcPort == DHCP_SERVER_PORT)) {
                                EbootProcessDHCP(
                                    &MyAddr,
                                    &dwSubnetMask,
                                    (BYTE *)pwUDPData,
                                    wUDPDataLen,
                                    &DHCPLeaseTime,
                                    &fGotIP);
                                if (fGotIP) {
                                    dwIPState = IPSTATE_GOTIP;
                                }
                            }
                            break;

                        case IPSTATE_ARPED:
                            pCfgData = NULL;
                            if (EbootProcessEDBG(&MyAddr,&EshellHostAddr,FrameBuffer,pwUDPData, wUDPDataLen, &fGotJumpimg, &pCfgData)) {
                                if (pCfgData) {
                                    if (pCfgData->Flags & EDBG_FL_DBGMSG) {
                                        EdbgOutputDebugString("Enabling debug messages over Ethernet, IP: %s, port:%u\n",
                                                              inet_ntoa(pCfgData->DbgMsgIPAddr),pCfgData->DbgMsgPort);
                                        memcpy(&pBootArgs->DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
                                        pBootArgs->DbgHostAddr.dwIP  = pCfgData->DbgMsgIPAddr;
                                        pBootArgs->DbgHostAddr.wPort = pCfgData->DbgMsgPort;
                                    }
                                    if (pCfgData->Flags & EDBG_FL_PPSH) {
                                        EdbgOutputDebugString("Enabling CESH over Ethernet, IP: %s, port:%u\n",
                                                              inet_ntoa(pCfgData->PpshIPAddr),pCfgData->PpshPort);
                                        memcpy(&pBootArgs->CeshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
                                        pBootArgs->CeshHostAddr.dwIP  = pCfgData->PpshIPAddr;
                                        pBootArgs->CeshHostAddr.wPort = pCfgData->PpshPort;
                                    }
                                    if (pCfgData->Flags & EDBG_FL_KDBG) {
                                        EdbgOutputDebugString("Enabling KDBG over Ethernet, IP: %s, port:%u\n",
                                                              inet_ntoa(pCfgData->KdbgIPAddr),pCfgData->KdbgPort);
                                        memcpy(&pBootArgs->KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
                                        pBootArgs->KdbgHostAddr.dwIP  = pCfgData->KdbgIPAddr;
                                        pBootArgs->KdbgHostAddr.wPort = pCfgData->KdbgPort;
                                    }
                                    pBootArgs->ucEshellFlags = pCfgData->Flags;

⌨️ 快捷键说明

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