📄 ethdbg.c
字号:
// 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 + -