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

📄 ethdbg.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    // Start interrupt thread. If we have clients registered, also turn on receive interrupts
    // from the ethernet controller, otherwise leave them disabled.
    if ((UCHAR) KITL_SYSINTR_NOINTR != Kitl.Interrupt) {
        KITL_DEBUGMSG(ZONE_INIT,("KITL Creating IST\n"));
        if ((hIntrThread = CreateKernelThread((LPTHREAD_START_ROUTINE)KITLInterruptThread,
                                              NULL, (WORD)g_dwKITLThreadPriority, 0)) == NULL) {
            KITLOutputDebugString("Error creating interrupt thread\n");
            return FALSE;
        }
    }

    // We won't use these event for anything other than storing the thread id's
    // of the kitl thread(s).
    SC_EventSetData (CreateEvent (NULL, FALSE, FALSE, _T("__KitlThreadId__")), (DWORD) hIntrThread);
    SC_EventSetData (CreateEvent (NULL, FALSE, FALSE, _T("__KitlTimerThreadId__")), (DWORD) hTimerThread);

    return TRUE;
}

static BOOL ChkCnxDsktp (LPVOID pUnused)
{
    return (KITLGlobalState & KITL_ST_DESKTOP_CONNECTED);
}

static BOOL TranCnxDsktp (LPVOID pParam, BOOL fUseSysCalls)
{
    return KitlSendFrame (PpfsFmtBuf, (WORD) (DWORD) pParam);
}

//
// KITLConnectToDesktop: Exchanging transport information with desktop
//
//      This function calls the transport function to retrieve device transport info,
//      send it to desktop, getting the transport infor from the desktop, and tell
//      the device transport about the desktop transport info.
//
static BOOL KITLConnectToDesktop (void)
{
    // we'll use the PpfsFmtBuf for send buffer since ppfs can't be started yet at this stage
    //
    PKITL_HDR pHdr = (PKITL_HDR) (PpfsFmtBuf + Kitl.FrmHdrSize);
    PKITL_DEV_TRANSCFG pCfg = (PKITL_DEV_TRANSCFG) KITLDATA(pHdr);
    USHORT cbData = sizeof (PpfsFmtBuf) - Kitl.FrmHdrSize - sizeof (KITL_HDR) - sizeof (KITL_DEV_TRANSCFG);

    if (!Kitl.pfnGetDevCfg ((LPBYTE) (pCfg+1), &cbData))
        return FALSE;

    memset (pHdr, 0, sizeof (KITL_HDR));
    pHdr->Id = KITL_ID;
    pHdr->Service = KITL_SVC_ADMIN;
    pHdr->Cmd = KITL_CMD_TRAN_CONFIG;
    cbData += sizeof (KITL_DEV_TRANSCFG);
    pCfg->wLen = cbData;
    pCfg->wCpuId = KITL_CPUID;
    memcpy (pCfg->szDevName, Kitl.szName, KITL_MAX_DEV_NAMELEN);
    cbData += sizeof (KITL_HDR);

    return KitlSendFrame (PpfsFmtBuf, cbData)
        && KITLPollResponse (FALSE, ChkCnxDsktp, TranCnxDsktp, (LPVOID) cbData);
}

static BOOL StartKitl (BOOL fInit)
{
    // KITL already started?
    if (!fInit && (KITLGlobalState & KITL_ST_DESKTOP_CONNECTED)) {
        return TRUE;
    }

    /*
     * When this function is called, the kernel hasn't yet been initialized,
     * so can't make any system calls.  Once the system has come up far
     * enough to handle system calls, KITLInitializeInterrupt() is called to complete
     * initialization.  This is indicated by the KITL_ST_MULTITHREADED flag in KITLGlobalState.
     */
    // Detect/initialize ethernet hardware, and return address information
    if (!OEMKitlInit (&Kitl))
        return FALSE;

    // verify that the Kitl structure is initialized.
    if (!Kitl.pfnDecode || !Kitl.pfnEncode || !Kitl.pfnRecv || !Kitl.pfnSend || !Kitl.pfnGetDevCfg || !Kitl.pfnSetHostCfg) {
        return FALSE;
    }

    // pfnEnableInt can not be null if using interrupt
    if (((UCHAR) KITL_SYSINTR_NOINTR != Kitl.Interrupt) && !Kitl.pfnEnableInt) {
        return FALSE;
    }

    if (Kitl.dwPhysBuffer || Kitl.dwPhysBufLen) {
        KITLOutputDebugString("\r\n!Kitl buffer specified by OAL is not required, ignore...\r\n");
    }

    Kitl.dwPhysBuffer = (DWORD)g_KitlBuffer;
    //Kitl.dwPhysBufLen = sizeof(g_KitlBuffer);
    Kitl.WindowSize = KITL_MAX_WINDOW_SIZE;

    KITLGlobalState |= KITL_ST_KITLSTARTED; // indicate (to kdstub) that KITL has started

    // If the initialized flag is already set, we are being called from the power on routine,
    // so reinit the HW, but not any state.
    if (!(KITLGlobalState & KITL_ST_ADAPTER_INITIALIZED)) {
        // perform the initial handshake with the desktop
        if (!KITLConnectToDesktop ()) {
            KITLOutputDebugString ("\r\n!Unable to establish KITL connection with desktop!\r\n");
            return FALSE;
        }

        // Set up kernel function pointers
        pKITLInitializeInterrupt = KITLInitializeInterrupt;
        pKITLSend = KITLSend;
        pKITLRecv = KITLRecv;

        KITLGlobalState |= KITL_ST_ADAPTER_INITIALIZED;

        if (Kitl.dwBootFlags & KITL_FL_DBGMSG)
            SetKernelCommDev (KERNEL_SVC_DBGMSG, KERNEL_COMM_ETHER);
        if (Kitl.dwBootFlags & KITL_FL_PPSH)
            SetKernelCommDev (KERNEL_SVC_PPSH, KERNEL_COMM_ETHER);
        if (Kitl.dwBootFlags & KITL_FL_KDBG)
            SetKernelCommDev (KERNEL_SVC_KDBG, KERNEL_COMM_ETHER);

        // only perform cleanboot if it's connected at boot. Cleanboot flag is
        // ignored if it's started dynamically.
        if (fInit && (Kitl.dwBootFlags & KITL_FL_CLEANBOOT)) {
            NKForceCleanBoot();
        }
        // if OEM calls KitlInit (FALSE), KITLInitializeInterrupt will
        // not be called in SystemStartupFuc. We need to initialize
        // interrupt here (when RegisterClient is called)
        if (fKITLcsInitialized && !InSysCall ()) {
            KITLInitializeInterrupt ();
        }
    }

    LOG (KITLGlobalState);
    return TRUE;
}


// KITLIoctl:
//  return TRUE: success
//         FALSE: failed
//         ERROR_NO_SUPPORT: unsupported control code
DWORD KITLIoctl (DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
    DWORD retval;

    switch (dwIoControlCode) {
    case IOCTL_EDBG_REGISTER_CLIENT:
        retval = (KITLRegisterClient(lpInBuf, lpOutBuf, (UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR *)lpBytesReturned));
        break;

    case IOCTL_EDBG_DEREGISTER_CLIENT:
        retval = (KITLDeregisterClient((UCHAR)nInBufSize));
        break;

    case IOCTL_EDBG_REGISTER_DFLT_CLIENT:
        retval = (KITLRegisterDfltClient((UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR **)lpInBuf, (UCHAR **)lpOutBuf));
        break;

    case IOCTL_EDBG_SEND:
        retval = (KITLSend((UCHAR)nInBufSize, lpInBuf, nOutBufSize));
        break;

    case IOCTL_EDBG_RECV:
        retval = (KITLRecv((UCHAR)nInBufSize, lpInBuf, lpOutBuf, nOutBufSize));
        break;

    case IOCTL_EDBG_SET_DEBUG:
        KITLSetDebug(nInBufSize);
        retval = 1;
        break;

    case IOCTL_EDBG_GET_OUTPUT_DEBUG_FN:
        retval = 0;
        if (nOutBufSize >= sizeof(VOID*)) {
            *(VOID**)lpOutBuf = (VOID*)KITLOutputDebugString;
            retval = 1;
        }
        break;

    case IOCTL_EDBG_IS_STARTED:
	    retval = (KITLGlobalState & KITL_ST_KITLSTARTED) ? 1 : 0; // indicate (to kdstub) that KITL has started
	    break;

    default:
        return ERROR_NOT_SUPPORTED;
    }
    return retval;

}


/*
 * KITLInit | Initialize debug Ethernet (KITL) subsystem.
 *
 * This function is called from the HAL to initialize the structures and hardware
 * used for debug Ethernet routines.  It must be called before any other
 * KITL functions are called, or kernel services are redirected to Ethernet
 * via SetKernelCommDev().  This function may be called very early in
 * system initialization, such as in OEMInit().  It should also be called
 * any time the debug Ethernet hardware needs to be reinitialized, such as
 * returning from OEMPowerOff().
 *
 * Return Value:
 *   Return TRUE if initialization was successful, FALSE if an error occurred.
 */

extern BOOL (*pfnIsDesktopDbgrExist) ();
extern DWORD (* pKITLIoCtl) (DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);

BOOL KitlInit (BOOL fStartKitl)
{
    // just initialize function pointers
    pKITLRegisterDfltClient  = KITLRegisterDfltClient;
    pKITLIoCtl = KITLIoctl;
    pfnIsDesktopDbgrExist = IsDesktopDbgrExist;

    // Initialize default clients
    NewClient (KITL_SVC_DBGMSG, KITL_SVCNAME_DBGMSG, FALSE);
    NewClient (KITL_SVC_PPSH,   KITL_SVCNAME_PPSH,   FALSE);
    NewClient (KITL_SVC_KDBG,   KITL_SVCNAME_KDBG,   FALSE);


    return fStartKitl? StartKitl (TRUE) : TRUE;
}

static void EnableInts()
{
    // Some platforms may not have available resources for an interrupt, in
    // which case we just continue to run in polling mode.
    if ((UCHAR) KITL_SYSINTR_NOINTR != Kitl.Interrupt) {
        KITL_DEBUGMSG(ZONE_INIT,("Enabling adapter ints...\n"));
        KCall((PKFN)Kitl.pfnEnableInt, TRUE);
        KITLGlobalState |= KITL_ST_INT_ENABLED;
    }
}

static DWORD KITLInterruptThread (DWORD Dummy)
{
    HANDLE hIntEvent;
    DWORD dwRet;

    KITL_DEBUGMSG(ZONE_INIT,("KITL Interrupt thread started (hTh: 0x%X, pTh: 0x%X), using SYSINTR %u\n",
                             hCurThread,pCurThread, Kitl.Interrupt));

    pCurThread->bDbgCnt = 1;   // no entry messages

    if ((hIntEvent = CreateEvent(0,FALSE,FALSE,EDBG_INTERRUPT_EVENT)) == NULL) {
        KITLOutputDebugString("KITL CreateEvent failed!\n");
        return 0;
    }
    if (!SC_InterruptInitialize(Kitl.Interrupt, hIntEvent, NULL,0)) {
        CloseHandle(hIntEvent);
        KITLOutputDebugString("KITL InterruptInitialize failed\n");
        return 0;
    }

    // always enable interrupt as long as OEM told us so
    EnableInts();

    KITLGlobalState |= KITL_ST_IST_STARTED;

    while ((dwRet = SC_WaitForMultiple (1,&hIntEvent,0,INFINITE)) == WAIT_OBJECT_0) {

        KITL_DEBUGLED(LED_IST_ENTRY,0);
        KITL_DEBUGMSG(ZONE_INTR,("KITL Interrupt event\n"));

        // no need to check pending, just call HandleRecvInterrupts because it'll
        // just return if there is no interrupt pending
        HandleRecvInterrupt(ISTRecvBuf,TRUE, NULL, NULL);

        SC_InterruptDone(Kitl.Interrupt);

        KITL_DEBUGMSG(ZONE_INTR,("Processed Interrupt event\n"));
    }
    KITLOutputDebugString("!KITL Interrupt thread got error in WaitForMultipleObjects: dwRet:%u, GLE:%u\n",
                          dwRet,GetLastError());
    return 0;
}

⌨️ 快捷键说明

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